C++ делегирование ctor и родительского ctor с аргументом
Это не похоже на работу в C++11:
class B : public A
{
public:
B(const A& a)
: A(a) // parent constructor for passing the parameter
, B() // delegating constructor for init of other members
{};
// ...
};
GCC говорит мне, что an initializer for a delegating constructor must appear alone
,
Как мне вызвать конструктор родительского класса с параметром и вызвать базовый конструктор класса B? (У меня есть куча других конструкторов в B, которые нуждаются в таком же поведении).
Прямо сейчас я рассматриваю возможность написания частного B::init()
функционировать и использовать его во всех телах конструктора, но это немного похоже на C++03.
Какое решение является предпочтительным?
2 ответа
Я полагаю, что предпочтительный способ делегирования заключается в обратном: он предназначен не для рефакторинга общих частей конструкторов, а для определения более простого варианта как особого случая более сложного случая.
Итак, вы должны начать с B(const A& a)
и использовать это как цель делегирования.
class B : public A
{
public:
B() : B(A());
B(const A& a) : A(a) // parent constructor for passing the parameter
{};
};
Ты звонишь A()
в любом случае при создании B
,
Логическое обоснование этого заключается в том, что когда у вас есть два "частично специализированных" c'tors, вы не сможете использовать их для инициализации сложного. Например:
class B : public A
{
public:
B() {};
B(int) : B() {};
B(double) : B() {};
B(double,int) : B(int), B(double) {}; // can't do it.
};
Я полагаю, что техническая причина объясняется в ответе Вирсавии. Посмотрите, что случилось бы, если бы у вас была общая роль в B()
:
class B : public A
{
public:
B() {};
B(int) : B() {};
B(double) : B() {};
B(double,int) : B(int), B(double) {}; //ooops would get B() called twice!
};
Это проблема алмазов, известная по наследству. Решение состоит в том, чтобы изменить логику.
class B : public A
{
public:
B() : B(0,0) {};
B(int a) : B(a,0) {};
B(double d) : B(0,d) {};
B(double a, int d) {/*full implementation*/};
};
B(const A& a) : A(a), B()
не имеет смысла, так как B()
также инициализирует базовый класс A
, По сути, это будет дублирующая инициализация, которая является внутренним противоречием.
Единственный реальный вариант для языка - запретить что-либо еще, если вы используете делегированный конструктор. Это то, что говорит вам ваш компилятор.