C++的多重继承
C++允许多重继承,多重继承是C++与其他一些流行语言不同的一个地方。比如在JAVA中就不存在多重继承,为此,当涉及到类似C++多重继承的场景时,JAVA之类的语言都使用“接口”的形式来实现目的,在C++里是没有接口的概念的,对应需求的使用对虚基类的多重继承来实现。下面就整理一下多重继承的基本用法和几个注意事项。
- 基类
class Base { public: int baseInt; };
- 继承自基类的两个并列的类
clase Left : public Base { Left() : Base() //注意要继承基类构造函数 { } };
clase Right : public Base { Right() : Base() //注意要继承基类构造函数 { } };
- 多重继承上面两个类
clase Multi : public Left, public Right { Multi() : Base(), Left(), Right() //继承所有基类构造函数 { } };
【注意】
上述多重继承方法的逻辑结构如下:Multi中会有重复的Base成员baseInt,当使用到该变量的时候会产生歧义而不通过编译
解决方法:
Left和Right继承Base时,使用virtual继承(这个virtual和虚函数无任何关系),类似下面这样:
clase Left : virtual public Base
【注意】
当使用Left* left指向一个Multi对象时,如果想使用从Right继承过来的变量或函数,我们会需要将这个Left类型的指针转换成一个Right型的指针,此时:
Right* right = (Right*)left; //错误
Right* right = dynamic_cast<Right*>(left); //正确,此时由于Left与Right在继承机构中是平级关系,该转换也成为交叉转换
原因:
由于继承过来的各种virtual函数,Multi对象中会对应每个直接继承的基类都维护一个vtable(这个部分请搜索这几个关键字去了解:virtual函数、动态绑定、运行时多态),按照继承的循序排列,vtable中保存从对应基类继承过来的函数的地址;直接强制转换会导致查错vtable