引言
在之前介绍过的单继承权限控制问题之后,在描述类多继承时会理解的比较容易。多继承的顾名思义就是继承子类会继承多个父类,继承的子类会同时得到多个父类的属性。多继承的权限控制就是单继承权限的累加过程,其实针对每一个父类的情况分析就和单继承一模一样。
class father { public: void seta(int a){tall=a;}; void print1(){std::cout<<"身高="<<tall<<endl;}; private: int tall; }; class mother { public: void setb(int b){weight=b;}; void print2(){std::cout<<"体重="<<weight<<endl;}; private: int weight; }; class son:public father,public mother { public: void setc(int c){age=c;}; void print3(){std::cout<<"年龄="<<age<<endl;}; private: int age; }; int main(int argc, char const *argv[]) { son a; a.seta(20); a.setb(30); a.setc(40); return 0; }
上面的代码中我们发现son子类继承的父类包含father和mother类。 多重继承中会出现两义性的问题,所谓两义性也就是在所继承的父类中出现了相同的函数,在调用的过程中不知道究竟这个函数来自哪个父类。下面给出两义性例子:
class A { public: void hello(){cout<<"This is A hello"<<endl;}; }; class B { public: void hello(){cout<<"This is B hello"<<endl;}; }; class C:public A,public B { public: }; int main(int argc, char const *argv[]) { /* code */ C test; //调用hello函数的时候不知道调用的是father的还是mother的? test.hello(); return 0; }
上面的例子中就出现了两义性,那么我们现在如何来排除两义性的出现。避免两义性出现的方法有两种:
(1) 通过域限定符
test.A::hello();
(2) 通过虚继承
在使用虚继承时我们会构造一个虚基类,虚基类中会包含定义了需要继承的方法。
#include using namespace std; class human { public: void run(){cout<<"人类可以行走"<<endl;} }; class father:public human { public: }; class mother { public: }; class son:public father,public mother { public: }; int main(int argc, char const *argv[]) { son.run(); return 0; }
通过虚基类的构造就会避免了继承过程中出现的两义性。
结论:
- 派生类的指针不能直接指向基类对象
- 派生类的指针必须强制转换为基类指针才可以指向基类的对象
- 指向基类对象的指针转化为派生类指针会崩溃
- 虚基类的指针或引用不能转换为派生类的指针或引用