文章前半部分引用: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_H
- class 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;
- }
- main.cpp: In function ‘int main()’:
- main.cpp:25: error: request for member ‘a’ is ambiguous
- fun.h:24: error: candidates are: int A::a
- fun.h:24: error: int A::a
- make: *** [all] 错误 1
- class B1:virtual public A
- class B2:virtual public A
- root@debian6:/home/michael/cppProject/angleInheritance# make
- g++ -c main.cpp
- g++ -o t main.o
- rm *.o
- root@debian6:/home/michael/cppProject/angleInheritance# ./t
- 12
若将C的继承顺序改为 “class C:public B2,public B1”后,结果则为11
- root@debian6:/home/michael/cppProject/angleInheritance# make
- g++ -c main.cpp
- g++ -o t main.o
- rm *.o
- root@debian6:/home/michael/cppProject/angleInheritance# ./t
- 11