не копировать конструктор предка
От: sci_reseacher  
Дата: 22.04.16 07:32
Оценка:
Иерархия классов получилось простой, как в схеме ниже. Предок содержит много параметров, к-е нужно инициализировать и много потомков (см. код ниже).


Можно ли как-то не копировать много раз конструктор A(с параметрами) в потомках и сохранить функционал (а именно конструктор с параметрами и по умолчанию)?
struct A {
    int __i;    
    float __f;
    // много параметров
    A(const int & _i = 1, const float & _f = 2.3 /*, много параметров*/): __i(_i), __f(_f) /*, много параметров*/  {}
    virtual work() = 0;
};

struct B : public A {
    double __d;
    B(const double & _d = 4): A(), __d(_d) {}
    B(const int & _i, const float & _f, /*, много параметров*/const double & _d ): A(_i,_f), __d(_d) {}
    virtual work() { /*работа*/ };
};

struct C : public A {
    bool __b;
    C(bool  _b = false): A(), __b(_b) {}
    C(const int & _i, const float & _f,/*, много параметров*/ bool _b ): A(_i,_f), __b(_b) {}
    virtual work() { /*работа*/ };
};

/*
* здесь много потомков типа A и B
*/


P.S. если в конструкторе A что-то меняется, приходится править конструкторы всех предков.
Re: не копировать конструктор предка
От: watchmaker  
Дата: 22.04.16 07:50
Оценка: 2 (1) +1
Здравствуйте, sci_reseacher, Вы писали:



_>Можно ли как-то не копировать много раз конструктор A(с параметрами) в потомках и сохранить функционал (а именно конструктор с параметрами и по умолчанию)?

Вариант 1. Использовать структуру параметров:
struct Params {
  int i = 1;
  float f = 2.3;
};
И в конструкторы передавать эту структуру, а не россыпь параметров. Так сразу значительно снизится количество копипасты.

Вариант 2. Шаблоны.
Записать конструктор наследника так:
struct B {
    ...

    template <typename... Args>
    B(const double & _d, Args... args): A(std::forward<Args>(args)...), d(_d) {}
    
    ...
};
Передаём все параметры в конструктор A за исключением нужного подмножества.
Но тут серьёзный недостаток — не видно сразу, а что именно и каких типов принимает конструктор B.



_> int __i;

_> float __f;
Имена с двойным подчёркиванием зарезервированы. Так писать не стоит — может неожиданно что-то сломаться.
Re[2]: не копировать конструктор предка
От: sci_reseacher  
Дата: 22.04.16 08:01
Оценка:
Здравствуйте, watchmaker, Вы писали:

_>> int __i;

_>> float __f;
W>Имена с двойным подчёркиванием зарезервированы. Так писать не стоит — может неожиданно что-то сломаться.

А можно поподробнее --- кем зарезервиравоны имена с двойным подчеркиванием?

например, в stl_vector.h такой стиль:
 vector(const vector& __x) 
       : _Base(__x.size()
// ...
Re[3]: не копировать конструктор предка
От: watchmaker  
Дата: 22.04.16 08:11
Оценка:
Здравствуйте, sci_reseacher, Вы писали:

_>Здравствуйте, watchmaker, Вы писали:


_>>> int __i;

_>>> float __f;
W>>Имена с двойным подчёркиванием зарезервированы. Так писать не стоит — может неожиданно что-то сломаться.

_>А можно поподробнее --- кем зарезервиравоны имена с двойным подчеркиванием?

Вот выдержка из стандарта http://stackoverflow.com/a/228797

_>например, в stl_vector.h такой стиль:

Если ты посмотрел в stl_vector.h и решил, что это хороший стиль названия переменных, то это была большая ошибка. Вся реализация вектора написана в таком вырвиглазном стиле как раз для того, чтобы у него было как можно меньше шансов конфликтовать с именами из нормальных программ
Просто это не твой код, а детали реализации языка. Тебе запретили использовать два подчёркивания в идентификаторе для того, чтобы у реализации вектора была возможность хоть как-то назвать свои переменные или типы, и при этом не создать конфликт с какими-нибудь пользовательскими именами и макросами.
Re[2]: не копировать конструктор предка
От: _hum_ Беларусь  
Дата: 22.04.16 08:19
Оценка: 2 (1)
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, sci_reseacher, Вы писали:




_>>Можно ли как-то не копировать много раз конструктор A(с параметрами) в потомках и сохранить функционал (а именно конструктор с параметрами и по умолчанию)?

W>Вариант 1. Использовать структуру параметров

W>Вариант 2. Шаблоны.


а как же наследуемые конструкторы?

stroustrup.com/C++11/Inherited constructors

struct B1 {
B1(int) { }
};

struct D1 : B1 {
using B1::B1; // implicitly declares D1(int)
int x;
};

Re[4]: не копировать конструктор предка
От: sci_reseacher  
Дата: 22.04.16 08:21
Оценка:
Здравствуйте, watchmaker, Вы писали:



_>>А можно поподробнее --- кем зарезервиравоны имена с двойным подчеркиванием?

W>Вот выдержка из стандарта http://stackoverflow.com/a/228797

ясно.

А как тогда именовать? ну например у меня есть параметр число чего-нибудь nSomething. Я делаю метод возвращающий это число, хочу хранить это число в скрытом поле и использовать фактический параметр. Как в stl_* можно было бы пользоваться одним именем:
class A {
  int _nSomethong;
public:
  A(const int & __nSomethong = 0 // ...
  int nSomething() const { return _nSomething; } 
}
Re[5]: не копировать конструктор предка
От: _hum_ Беларусь  
Дата: 22.04.16 08:41
Оценка:
Здравствуйте, sci_reseacher, Вы писали:

_>Здравствуйте, watchmaker, Вы писали:




_>>>А можно поподробнее --- кем зарезервиравоны имена с двойным подчеркиванием?

W>>Вот выдержка из стандарта http://stackoverflow.com/a/228797

_>ясно.


_>А как тогда именовать? ну например у меня есть параметр число чего-нибудь nSomething. Я делаю метод возвращающий это число, хочу хранить это число в скрытом поле и использовать фактический параметр. Как в stl_* можно было бы пользоваться одним именем:

_>
_>class A {
_>  int _nSomething;
_>public:
_>  A(const int & __nSomething = 0 // ...
_>  int nSomething() const { return _nSomething; } 
_>}
_>



я делаю так

class A 
{
  int m_nSomething;

public:
  //--------------------------------------
  A(const int nSomething = 0)
    : m_nSomethong(nSomething)
  {<...>}
  //--------------------------------------
  int nSomething(void) const { return m_nSomething; }
  //-------------------------------------- 
};
Re[5]: не копировать конструктор предка
От: Ops Россия  
Дата: 22.04.16 18:09
Оценка:
Здравствуйте, sci_reseacher, Вы писали:

_>А как тогда именовать? ну например у меня есть параметр число чего-нибудь nSomething. Я делаю метод возвращающий это число, хочу хранить это число в скрытом поле и использовать фактический параметр. Как в stl_* можно было бы пользоваться одним именем:


Обычно используют префикс "m_" или, чуть реже, суффикс из одиночного подчеркивания. Вообще выбор за тобой, имеешь право придумать что-то свое, однако лучше использовать распространенные практики, тогда твой код будет проще понять другим.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re: не копировать конструктор предка
От: Current  
Дата: 16.05.16 11:57
Оценка:
может так?

struct A {
    virtual work() = 0;
};
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.