這個佈局在C++中是不可行的,即使有額外的幫助類也是如此。
B從A繼承的事實,並且您希望在C的一側和D在另一側共享A繼承,需要B,C和D實際上從A繼承。但是,A會是共享您的鑽石的兩個分支。
替代品
還有什麼替代方案?
這最後的解決方案不能滿足您的要求,但將如下所示:
struct Base { int x; };
struct A : public virtual Base { int a; };
struct AC : public A{}; // synonym
struct B : public virtual A { int b; };
struct BC : public virtual AC { int b; }; // !! clone !!
struct C : public virtual AC { int c; };
struct D : public virtual A { int d; };
struct E : public BC, C { int e; };
struct F : public B, D { int f; };
struct Final : public E, F { };
而這裏訪問的承包商,客人:
Final f;
f.x = 2; // unambiguous: there's onely one of it
f.f = 1;
f.e = 2;
f.d = 3;
f.c = 4;
//f.b = 5; // ambiguous: there are two of it
f.E::b = 5; // successful desambiguation
f.F::b = 6; // successfuldesambiguation
//f.a = 7; // ambiguous: there are two of it
f.E::a = 7; // successful desambiguation
f.F::a = 8; // successful desambiguation
要回到你的問題陳述:你說你不能干預上述E和F.在這種情況下,你的選擇是非常有限的:
但效果會在共享相同的,如下面的代碼desmonstrates繼承(上上述一個的頂部):
class FI : private F // make F private
{ public:
void set_xa(int u, int v) { x = u; a= v; }
void show_xa() { cout << "x:" << x << " a:" << a << endl; }
};
class EI : private E // make E private
{
public:
void set_xa(int u, int v) { x = u; a = v; }
void show_xa() { cout << "x:" << x << " a:" << a << endl; }
};
struct Final3 : public EI, public FI { };
Final3 h;
h.EI::set_xa(3, 4);
h.FI::set_xa(5, 6);
h.EI::show_xa();
h.FI::show_xa();
// the shared virtually inherited memebers are still shared !
結論:
通過繼承,您完全被E和F之上的設計所束縛,從而不被允許影響。
所以第一個問題是:
- 你不能改變畢竟這種設計(即一個B的克隆)?
- 難道兩個分支之間都有一個分歧(可能畢竟有理由)嗎?
如果答案是否定的這兩個問題,你必須去組成,並實現了一種proxy design pattern,你的組成對象是你的兩個組件的代理。
你可以讓'A'爲班級模板嗎? – curiousguy
讓我們假設我可以。它會改變什麼? B類也需要決定,它想繼承哪種A的專業化。 –
如果你可以改變你的班級名稱(模板只是一種改變班級名稱的方法),你可以解決你的約束:模板 class B :public virtual A {' –
curiousguy