多重继承:一个类继承了多个父类。
特点:
1. 拥有全部父类的成员变量和成员函数
2. 子类可以当作任一父类使用
语法:
class Child : public Parent_1, public Parent_2, public Parent_3 { }
多重继承的构造函数? 先父类,后同级,再自己。
析构函数调用顺序?先自己,后同级,再父类。
使用指针时子类退化为哪一个父类?通过多重继承得到的对象可以拥有多个的代表自己的地址值。
#include <iostream> #include <string> using namespace std; class Parent_1 { public: int a; }; class Parent_2 { public: int b; }; class Child : public Parent_1, public Parent_2 // 多重继承 { public: int c; }; int main() { Child c; Parent_1* parent_p1 = &c; // 0x7fffff388bdc 根据指针类型Parent_1得到子类中相应的代表子类的指针 Parent_2* parent_p2 = &c; // 0x7fffff388be0 根据指针类型parent_2得到代表子类的的指针 void* void_p1 = &c; // 0x7fffff388bdc 无法得到子类中相应代表子类的指针 void* void_p2 = &c; // 0x7fffff388bdc 无法得到子类中相应代表子类的指针
return 0; }
继承多个父类结果是:多个代表子对象地址的指针指向子对象的不同部分。
如下图:pa,pb都代表指向子类本身的指针,但是其却指向子类中的不同内存地址。
多重闭合虚继承,例:
#include <iostream> #include <string> using namespace std; class People {
int m_age;
string m_name; public:
void People(string name ,int age)
{
m_name = name;
m_age = age;
}
void print()
{
cout << name << age << endl;
}
}; class Teacher : virtual public People // 虚继承 { public: Teacher(string name, int age) : People(name, age) {} // :号表示调用父类的构造函数 }; class Student : virtual public People // 虚继承 { public: Student(string name, int age) : People(name, age){} // :号表示调用父类构造函数 }; class Doctor : public Teacher, public Student { public: Doctor(string name, int age) : Teacher(name, age), Student(name, age), People(name, age) { } }; int main() { Doctor d("Delphi", 33); d.print(); // 直接继承时,error 父类teacher和student都有people父类。 虚继承时,OK,打印同一内容。 d.Teacher::print(); // 作用域限定符,指定父类 d.Student::print(); return 0; }
多重继承解决办法:虚继承
虚继承语法:继承同一父类时加上virtual关键字
class People{}; class Teacher : virtual public People{}; class Student : virtual public People{}; class Doctor : public Teacher,public Student
虚继承缺点:中间层不再自动调用父类构造函数,需要子类直接调用父类的构造函数