Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 避免钻石遗产_C++_Design Patterns_Inheritance_Diamond Problem - Fatal编程技术网

C++ 避免钻石遗产

C++ 避免钻石遗产,c++,design-patterns,inheritance,diamond-problem,C++,Design Patterns,Inheritance,Diamond Problem,我有一门课a A / \ B C 类B和C是从类A派生的接口 A / \ B C 现在我必须为B和C实现类D和E 还有一些类别:FDB,GDC,HEC,IEB,JDB,KDC,LEB,MEC(而这些类名称末尾的DB和DC意味着类使用D和B作为DB的结尾,使用D和C作为DC,E和B作为EB的结尾,等等。) 因此: 但是我有钻石遗产,我不想要它 有人能推荐另一种设计吗 感谢您的帮助!您希望/需要避免多重继承的原因是什么

我有一门课
a

      A
    /   \
   B     C
B
C
是从类
A
派生的接口

      A
    /   \
   B     C
现在我必须为
B
C
实现类
D
E

还有一些类别:
FDB
GDC
HEC
IEB
JDB
KDC
LEB
MEC
(而这些类名称末尾的
DB
DC
意味着类使用
D
B
作为
DB
的结尾,使用
D
C
作为
DC
E
B
作为
EB
的结尾,等等。)

因此:

但是我有钻石遗产,我不想要它

有人能推荐另一种设计吗


感谢您的帮助!

您希望/需要避免多重继承的原因是什么

无论哪种方式,如果在某些情况下不能(不希望)使用继承,请使用封装:

class A..

class `B`: public virtual `A`..
class `C`: public virtual `A`..

class `D`: public B {
private:
    C c_instance_;
};
class `E`: public B {
    C c_instance_;
};

... 
为了避免代码重复,您可以创建一个C(或D)持有者,并通过受保护的继承和CRTP继承它。这样,一个单独的基类保存C基类功能,但从它继承的类没有公共基类:

class A..

class B: public A..
class C: public A..

template<class Specialized, class DependedOn>
class DependsOn {
protected:
    DependedOn& get() { return implementation_; }
private:
    DependedOn implementation_;
};

class D: public B, protected DependsOn<D, C> .. // inheritance with CRTP
class E: public B, protected DependsOn<E, C> .. // inheritance with CRTP

class FDB: public D, protected DependsOn<FDB, B> .. 
A类。。
B类:公共A类。。
C类:公共A类。。
模板
类DependsOn{
受保护的:
DependedOn&get(){返回实现}
私人:
取决于执行情况;
};
D类:公共B,受保护的DependsOn..//CRTP继承
E类:公共B,受保护的Dependesson..//CRTP继承
FDB类:公共D,受保护的依赖项。。
D
E
FDB
等将在内部使用
get()
方法(或者更具体地说,
DependsOn::get()
DependsOn::get()
等)来实现公共接口


因为
DependsOn
不同于
DependsOn
,所以您只有一个由整个层次结构实现的公共接口。

我可以问一下您为什么不需要它吗?这可能就是虚拟继承的目的。可能的答案可以找到。哦,亲爱的上帝。真的吗?所有这些缩写……如果您告诉我们为什么需要它,也许我们会展示出来一个间接解决问题的解决方案,我认为没有一个真正的应用程序需要这个问题。@MM.有一些虚拟继承和大多数派生细节的整洁应用程序,以及所有这些,例如,模拟命名模板参数(Vandevoorde&Josuttis中有一个很好的章节).但你绝对正确:普通用户代码应该远离如此庞大的类层次结构。