菱形继承问题

来源:互联网 发布:js json 取值 编辑:程序博客网 时间:2024/03/29 00:07

文章前半部分引用:http://blog.csdn.net/icerlion/article/details/4409618

考虑这种情况:

class CA{};

class CB : public CA{};

class CC : public CA{};


这时我们需要一个CD类,它需要同时继承CB和CC。

问题就出现了。

如果我们这样写:

class CD : public CB, public CC{};

 

那么我们在构造一个CD类的时候,

其结果如下:

一个孙子有两个爷爷

 

即:一个CD类中有两个CA(它的超类的对象)

这样的情况是不合理的。此时会出现模糊调用的现象。

 

如何避免这种现象呢?

虚继承就有了用武之地。

 

我们需要改写CB和CC的继承方式。

class CB : public virtuel CA{};

class CC : public virtual CA{};

 

其他无需修改。此时我们构造一个CD类的时候,

其顺序如下:

开始构造CD类,

先构造一个超类CA,然后构造CB,

在构造CC(此时不会构造CC的父类CA)

这样一来,

CD类对象中包含的CB和CC将共享同一份CA对象。

 一个孙子就只有一个爷爷

这时就不会出现模糊调用的现象了。

 

这个就是C++臭名昭著的多继承。

在JAVA中根本不会出现这种情况,

如果必须使用菱形继承的时候务必使用虚拟继承。

如果你的项目中有太多的菱形继承,

你或许应该重新考核一下你的软件工程师。

--------------------------------------------------------------------------

例子:

fun.h

#ifndef FUN_H#define FUN_Hclass A{public:    int a;    A()    {        a=10;    }};class B1:public A //没有使用虚继承{public:    int b1;    B1()    {        b1=1;        a=11;    }};class B2:public A //没有使用虚继承{public:    int b2;    B2()    {        b2=2;        a=12;    }};class C:public B1,public B2{public:    int c;    C()    {        c=3;    }};#endif



// main.cpp

#include "fun.h"#include <iostream>using namespace std;int main(){    C *pc=new C();    cout<<pc->a<<endl;    return 0;}


编译不通过,提示A的数据成员a为模糊调用;

main.cpp: In function ‘int main()’:main.cpp:25: error: request for member ‘a’ is ambiguousfun.h:24: error: candidates are: int A::afun.h:24: error:                 int A::amake: *** [all] 错误 1


当将fun.h中B1、B2改为虚拟继承A之后则可编译通过;

class B1:virtual public Aclass B2:virtual public A


同时运行结果将为12,

root@debian6:/home/michael/cppProject/angleInheritance# makeg++ -c  main.cppg++ -o t main.orm *.oroot@debian6:/home/michael/cppProject/angleInheritance# ./t12
结果12的原因是C类构造函数C()会先调用虚基类A的构造函数A(),然后再调用自身父类构造函数B1(),B2(),调用顺序是根据“class C:public B1,public B2”从左向右依次进行。


若将C的继承顺序改为 class C:public B2,public B1”后,结果则为11

root@debian6:/home/michael/cppProject/angleInheritance# makeg++ -c  main.cppg++ -o t main.orm *.oroot@debian6:/home/michael/cppProject/angleInheritance# ./t11







原创粉丝点击