[英]How to use parameterized base class constructor downstream of virtual inheritance
[英]How to avoid calling a too much parameterized constructor, with virtual inheritance?
我想通過以下明顯的示例執行虛擬繼承:
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(a,b)和C(a,c),因為對於虛擬繼承的這種特殊情況,參數B在B和C構造函數中沒有用。
我發現以下文章,其中Jack Reeves提出了一些替代方案來調用默認構造函數。
http://www.drdobbs.com/cpp/multiple-inheritance-considered-useful/184402074?pgno=2
引用:
如果必須先完全初始化A,然后才能構造B和C,則必須對構造函數進行初始化,然后返回到我最初顯示的內容。 另外,也許您可以通過以下方式獲得幫助:
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中實現了單個參數構造函數(在實踐中從未調用過),該構造函數使用正向構造函數訪問類內部的“最簡單”有效構造函數(保持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中定義第二個構造函數?
有什么缺點?
我的答案是:
enum
, A
的構造函數,則必須聲明其他構造函數 。 但是,如果您不...將默認構造函數與init
函數一起使用, 或僅使用常規的參數化構造函數, A
類中A
更多代碼, B
類中的更多代碼, C
類中的更多代碼, init
函數或參數化的構造函數 樣本(未整理)代碼:
class A
{
public:
A(int a) : m_a(a) {}
protected:
A() = default;
void initA(int a) { m_a = a; } // optional
private:
int m_a;
};
class B : virtual public A
{
public:
B(int a, int b) : A(a), m_b(b) {}
protected:
B(int b) : 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) : 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) {}
// or optionally:
D(int a, int b, int c) : B(b), C(c) { initA(a); }
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.