Я хочу, чтобы выполнить виртуальное наследование со следующим очевидным примером:Как избежать вызова слишком большого параметризованного конструктора с виртуальным наследованием?
class A
{
public:
A(int a) : m_a(a) {}
private:
int m_a;
};
class B : virtual public A
{
public:
B(int a, int b) : A(a), m_b(b) {}
private:
int m_b;
};
class C : virtual public A
{
public:
C(int a, int c) : A(a), m_c(c) {}
private:
int m_c;
};
class D : public B, public C
{
public:
D(int a, int b, int c) : A(a), B(a, b), C(a, c) {}
};
Но я не хочу называть B (а, Ь) и С (а, с), поскольку параметром а бесполезно B и C для этого конкретного случая виртуального наследования.
Я нашел следующую статью, где Джек Ривз предлагает несколько альтернатив, чтобы вызвать конструкторы по умолчанию.
http://www.drdobbs.com/cpp/multiple-inheritance-considered-useful/184402074?pgno=2
Цитата:
Если мы должны полностью инициализировать перед В и С могут быть построены, то мы должны сделать инициализацию с конструктором, и мы вернулись к тому, что я показал в первой. В качестве альтернативы, возможно, вы можете получить что-то вроде следующего:
class B : public virtual A { // class C is similar
public:
B(int x) : A(x) {}
protected:
B() : A(0) {}
};
class D : public B, public C {
public:
D(int x) : A(x) {} // B and C are default constructed
};
Конец цитаты.
Итак, я сохранил эту идею защищенного конструктора, но я не хочу использовать конструктор по умолчанию. Я реализовал конструктор сингулярных параметров в A (никогда не называемый на практике), которые используют конструктор forward для «самого простого» допустимого конструктора внутри класса (сохраняйте инкапсуляцию того, что B и C должны вызвать внутри A). Единственный параметр здесь, чтобы дать уникальную подпись этому конструктору «bastard».
// new way
namespace VIRTUAL_INHERITANCE {
struct NEVER_CALLED {};
}
class A
{
public:
A(int a) : m_a(a) {}
protected:
A(VIRTUAL_INHERITANCE::NEVER_CALLED vinc) : A(0) {}
private:
int m_a;
};
class B : virtual public A
{
public:
B(int a, int b) : A(a), m_b(b) {}
protected:
B(int b) : A(VIRTUAL_INHERITANCE::NEVER_CALLED()), m_b(b) {}
private:
int m_b;
};
class C : virtual public A
{
public:
C(int a, int c) : A(a), m_c(c) {}
protected:
C(int c) : A(VIRTUAL_INHERITANCE::NEVER_CALLED()), m_c(c) {}
private:
int m_c;
};
class D : public B, public C
{
public:
D(int a, int b, int c) : A(a), B(b), C(c) {}
};
Мои вопросы:
Как избежать вызова слишком много параметризированный конструктор, с виртуальным наследованием?
Возможно ли улучшить технику «уникальной подписи», сделав что-то еще (с перечислением, например)?
Есть ли у кого-то лучшая техника, чтобы сделать то же самое без необходимости определять второй конструктор в A?
Каковы недостатки?
Цитирование: Очевидное не компилируется: Класс D: B, публичное общественное C { общественности: D (INT х): В (х), С (х) {}} ; Это вызывает ошибку, жалуясь на отсутствие конструктора по умолчанию для A. Для выполнения этой работы мы должны написать: D (int x): A (x), B (x), C (x) {} Хотя это действительно работает, это выглядит глупо, потому что вызов инициализатора для A игнорируется в конструкторах B и C при вызове для объекта D. – Cevik
Какую проблему программирования вы на самом деле пытаетесь решить? – gnasher729
Вы прочитали весь пост? Мои вопросы завершаются. – Cevik