C++代码重用(二)

多重继承

多重继承描述的是有多个直接基类的类,与单继承一样,公有多重继承表示的都是is-a的关系。而私有多重继承和保护多重继承表示的是has-a的关系。

下面我们看一个例子:

class Base{...};
class BaseA : public Base{...};
class BaseB : public Base{...};
class Abc : public BaseApublic BaseB{...};

···

Abc abc;
Base * base = &abc;  //将出现二义性

针对上例,类Abc多重继承了BaseABaseB两个类,由于BaseABaseB都继承了Base,因此Abc包含了两个Base组件,因此在将派生类类对象的地址赋值给基类指针的时候,会出现二义性。abc包含两个Base对象,有两个地址可供选择,所以可以使用类型转换来指定对象:

Base * base1 = (BaseA*)&abc;
Base * base2 = (BaseB*)&abc;

这样虽然可以解决上例子带来的二义性,但使得使用基类指针来引用不同的对象(多态性)复杂化。而且实际应用中Abc类也不需要包含两个Base对象。因此c++引入了虚基类的概念来解决该情况下的多重继承。

虚基类使得从多个类(他们的基类相同)派生出来的对象只继承一个基类对象。具体的做法如下:

class Base{...};
class BaseA : virtual public Base{...};
class BaseB : public virtual Base{...}; //virtual与public的顺序不做要求,两种写法都是对的
class Abc : public BaseApublic BaseB{...};

这样做可以保证Abc类对象中只会包含Base类对象的一个副本。从本质上讲,应该是继承的BaseABaseB类对象共享了一个Base对象。这样就可以简单的使用多态。

针对虚基类,在设计的时候需要对其类构造函数采用一种新的方法。例如:

class Base{
    int base;
    public:
    Base(int ba = 0):base(ba){}};

class BaseA : virtual public Base{
    int a;
    public:
    BaseA(int a = 0,int ba = 0): Base(ba),a(a){}
};

class BaseB : virtual public Base{
    int b;
    public:
    BaseC(int b = 0,int ba = 0): Base(ba),b(b) {}
}; 

class Abc : public BaseApublic BaseB{
    int abc;
    public:
    Abc(int a = 0,int b = 0,int ba = 0; int abc = 0):BaseA(a, ba), BaseB(b, ba), abc(abc){}// flawed
    Abc(int a = 0,int b = 0,int ba = 0; int abc = 0):Base(ba), BaseA(a, ba), BaseB(b, ba), abc(abc){}
};

其中,对于:

Abc(int a = 0,int b = 0,int ba = 0; int abc = 0):BaseA(a, ba), BaseB(b, ba), abc(abc){}// flawed

Base是虚基类的时候,Abc类通过BaseABaseB的构造函数将参数信息间接传递给Base时将不起作用,c++在基类是虚的时候,禁止将参数信息通过中间类传递给基类。因此上述ba的信息必不能传递给子对象Base,然而编译器会使用Base的默认构造函数,在构造派生类对象之前构造基类对象组件。如果不希望使用默认构造函数来构造虚基类函对象,则需要显式地调用基类构造函数。因此构造函数如下:

Abc(int a = 0,int b = 0,int ba = 0; int abc = 0):Base(ba), BaseA(a, ba), BaseB(b, ba), abc(abc){}

:上述代码显式地调用Base的构造函数,是合法的,但是对于非虚基类,则是非法的。)

如果类有间接虚基类,则除非只使用该虚基类的默认构造函数,否则必须显式地调用该虚基类的某个构造函数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艰默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值