多重继承

多重继承(MI),说简单点就是一个派生类继承了多个基类。
在面向对象程序设计时,我们需要MI,比如:在一个家庭中,孩子同时继承了父亲和母亲的一些特性;如果用单继承该怎么弄?
我们每天使用的类iostream就是多重继承出来的,MI在iostream中的作用是代码重用。

MI在日常编码中用的很少,主要原因是:
        1. 一些“特性”被加入标准C++(尤其是模板)后,改变了我们的对程序的认识,MI的地位逐渐下降。   比如:一个类需要容器A中的属性,也需要容器B中的属性,使用MI可以达到目的;模板的加入改变了创建容器的方法,所以在这种情况下,减少了使用MI的动力。
       2. 使用MI时容易出现“菱形继承”
比如:

class A {public: int data;}; 
class B: public A{}; 
class C: public A{}; 
class D: public B, public C{}; 

这时,D继承的是B中的data还是C中的data呢?

接口的MI是没有争议的,接口隐藏了数据和方法。(接口中所有的函数都是纯virtual函数,析构函数除外)。

 

有时,我们需要一个“菱形继承”,如何解决“菱形继承”问题呢?
1.  虚继承 + using B::data, 显示的调用B::data

#include <iostream>
using namespace std;
class A 
{
  public: int data;
}; 
class B: virtual public A{}; 
class C: virtual public A{};
class D: public B, public C
{
public:
  using B::data;
}; 
int main()
{
  D d;
  d.data;
  return 1;
}


2. 虚继承 +  隐藏或覆盖(继承的函数为虚函数)
按照作用域的规则,在继承层次结构中类B比A处于“更高的派生层次”,那么名字B::func就比名字A::func占优势(dominate)。

#include <iostream>
using namespace std;
class A 
{
public: 
  void func()
  {
    cout<<"A"<<endl;
  }
  virtual ~A() {}
}; 

class B: virtual  public A
{ 
public:
 void func()
 {
   cout<<"B"<<endl;
 }
}; 

class C: virtual public A
{
}; 

class D: public B, public C
{
}; 

int main()
{
  D d;
  d.func();
  return 1;
}

 

如果在MI的层次结构中没有“菱形”的继承结构出现,MI将是相当简单的。如果菱形继承结构出现,就需要通过引入虚基类来消除重复子对象。这不仅增加了混乱,而且使接下来的表达方式变得更加复杂和低效(虚继承会带来额外的开销和不同的意义)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值