C++之钻石问题和解决方案(菱形继承问题)
来源:互联网 发布:华为手机4g网络用不了 编辑:程序博客网 时间:2024/04/29 00:52
C++之钻石问题和解决方案(菱形继承问题)
分类: C/C++2012-12-27 14:17 260人阅读 评论(0) 收藏 举报
c++C++diamond problem多重继承菱形继承问题钻石问题
在C++中,什么叫做钻石问题(也可以叫菱形继承问题),怎么避免它?
下面的图表可以用来解释钻石问题。
假设我们有类B和类C,它们都继承了相同的类A。另外我们还有类D,类D通过多重继承机制继承了类B和类C。因为上述图表的形状类似于钻石(或者菱形),因此这个问题被形象地称为钻石问题(菱形继承问题)。现在,我们将上面的图表翻译成具体的代码:
- /*
- Animal类对应于图表的类A
- */
- class Animal { /* ... */ }; // 基类
- {
- int weight;
- public:
- int getWeight() { return weight;};
- };
- class Tiger : public Animal { /* ... */ };
- class Lion : public Animal { /* ... */ }
- class Liger : public Tiger, public Lion { /* ... */ };
在上面的代码中,我们给出了一个具体的钻石问题例子。Animal类对应于最顶层类(图表中的A),Tiger和Lion分别对应于图表的B和C,Liger类(狮虎兽,即老虎和狮子的杂交种)对应于D。
现在,问题是如果我们有这种继承结构会出现什么样的问题。
看看下面的代码后再来回答问题吧。
- int main( )
- {
- Liger lg ;
- /*编译错误,下面的代码不会被任何C++编译器通过 */
- int weight = lg.getWeight();
- }
在我们的继承结构中,我们可以看出Tiger和Lion类都继承自Animal基类。所以问题是:因为Liger多重继承了Tiger和Lion类,因此Liger类会有两份Animal类的成员(数据和方法),Liger对象"lg"会包含Animal基类的两个子对象。
所以,你会问Liger对象有两个Animal基类的子对象会出现什么问题?再看看上面的代码-调用"lg.getWeight()"将会导致一个编译错误。这是因为编译器并不知道是调用Tiger类的getWeight()还是调用Lion类的getWeight()。所以,调用getWeight方法是不明确的,因此不能通过编译。
钻石问题的解决方案:
我们给出了钻石问题的解释,但是现在我们要给出一个钻石问题的解决方案。如果Lion类和Tiger类在分别继承Animal类时都用virtual来标注,对于每一个Liger对象,C++会保证只有一个Animal类的子对象会被创建。看看下面的代码:
- class Tiger : virtual public Animal { /* ... */ };
- class Lion : virtual public Animal { /* ... */ }
你可以看出唯一的变化就是我们在类Tiger和类Lion的声明中增加了"virtual"关键字。现在类Liger对象将会只有一个Animal子对象,下面的代码编译正常:
- int main( )
- {
- Liger lg ;
- /*既然我们已经在Tiger和Lion类的定义中声明了"virtual"关键字,于是下面的代码编译OK */
- int weight = lg.getWeight();
- }
- Class Mule implements Horse,Donkey
- {
- /* Horse和Donkey是接口*/
- C++之钻石问题和解决方案(菱形继承问题)
- C++之钻石问题和解决方案(菱形继承问题)
- 钻石问题(菱形继承问题) 和虚继承
- C++名字冲突问题和钻石继承
- c++钻石-菱形继承
- 菱形继承->菱形虚拟继承(继承系列问题)
- volatile的作用和菱形继承问题
- 菱形继承问题
- 菱形继承问题
- 菱形继承问题(default)
- 菱形继承引发的问题和解决方案,以及底层实现的原理.
- c++-关于菱形继承&虚继承的问题总结
- 钻石问题 diamond problem 多继承问题
- DiamondProblem(钻石问题)
- 【C++】继承和多态之——菱形继承
- C++ 菱形继承问题 虚继承和虚基类
- 【C++】继承(菱形继承)
- 钻石继承的构造函数问题
- Ubuntu利用Samba映射磁盘到Windows
- RIA(Rich Internet Appl…
- RIA大潮中,哪种技术适合你?
- 为何选择Flex和PHP
- Flex搜索引擎收录的问题以及seo优…
- C++之钻石问题和解决方案(菱形继承问题)
- linux忘记mysql密码处理方法
- linux下用Apache一个IP多个网站多…
- 2011-04-12 18:19 Linux…
- Linux编译安装LAMP
- phpize是什么
- 在windows平台下MySql启动时…
- ThinkPHP的CURD方法及查询方法一览
- Web负载均衡解决方案 HAproxy