限制C+中虚拟基类的对象共享+; 我知道C++中的物理继承和虚拟继承。然而,我想知道这个模型是否可以通过任何设计模式或技巧来实现

限制C+中虚拟基类的对象共享+; 我知道C++中的物理继承和虚拟继承。然而,我想知道这个模型是否可以通过任何设计模式或技巧来实现,c++,inheritance,multiple-inheritance,modeling,virtual-inheritance,C++,Inheritance,Multiple Inheritance,Modeling,Virtual Inheritance,不应修改E类和F类及其基。。假设它们来自外部图书馆 E和F下面的所有内容都是开放的。可以引入中间帮助类、非成员函数、模板。。。实现这一点的一切: BaseClass / \ / \ A A / \ / \ / \ / \ B C B D \ /

不应修改E类和F类及其基。。假设它们来自外部图书馆

E和F下面的所有内容都是开放的。可以引入中间帮助类、非成员函数、模板。。。实现这一点的一切:

           BaseClass
           /       \
          /         \
         A           A
        / \         / \
       /   \       /   \
      B     C     B     D
       \   /       \   /
        \ /         \ /
         E           F
          \         /
           \       /
            \     /
           FinalClass
注意,E和F不应共享A。最终类应包含2 A。 我的问题是,创建E或F需要B、C和D实际上继承A。。但是,如果A是一个虚拟基类,那么编译器只会在FinalClass中创建一个A对象,而不是两个不同的对象

所以,我想你们中的许多人会建议在这里使用组合而不是继承。然而,组合在这里建模的是“有”关系,而不是“是”关系。
在解释中,我希望FialLeCar真正像E或F一样,包括将它转换成那些类。

< P>在C++中,这种布局是不可行的,即使有额外的帮助类。p> 事实上,B从A继承,而你想在一边与C共享A继承,在另一边与D共享,这要求B、C和D实际上从A继承。但是,A将在钻石的两个分支上共享

选择 还有什么选择呢

  • 如果你想打破钻石左右分支之间的A共享,你也会打破公共基础的共享

  • 如果引入一些中间类A1、A2来实现分支中的左共享和右共享,那么您会发现两个B必须继承其中一个或另一个

  • 唯一的出路可能是为B创建一个重复的类

最后一个解决方案不满足您的要求,但看起来如下所示:

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以上。在这种情况下,你的选择非常有限:

  • 你公开继承遗产
  • 您可以通过一些中间类进行私有继承
但对共享的影响是相同的,如下代码演示(在上面的代码顶部):

class-FI:private F//make F private
{公众:
空集_xa(intu,intv){x=u;a=v;}

void show_xa(){如果A不是虚拟的,B和C或者B和D如何共享一个A?@JackSabbath-完全正确,对不起:我已经把这个问题读给fast了,没有注意到两个常见的B。我已经做了全面的编辑。非常感谢你的详细解释。我确实问了这个问题,因为我是一个图书馆的作者,所以我想弄清楚这个设计是否gn模式在实现它之前是一条死胡同。我认为我的模型可以实现,如果E从a物理派生,而B和C不会从a派生,而是使用奇怪的循环模板模式来访问a,E继承了a。图的另一侧也是如此。当然,B的类型不会相同(CRTP专门化)。他们需要一个接口基类。我最好还是忘了这个模式。你能把
A
做成一个类模板吗?让我们假设我能。它会改变什么?类B还必须决定它要继承的A的哪个专门化。如果你能改变你的类名(模板只是更改类名的一种方式),您可以解决约束
模板类B:public virtual a{
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 !