继承的基本语法:class 子类(派生类) :继承方式 父类(基类)
继承方式:
继承中的对象模型(从父类继承过来的成员,哪些属于子类对象中):
父类中的所有非静态成员属性都会被子类继承下去(包括private)!
父类中的 私有成员属性 是被编译器隐藏了,所以访问不到,但确实被继承下去了!
继承中构造函数和析构函数的顺序:
先构造父类,再构造子类!
析构的顺序一般与构造函数的顺序相反。 (压栈——后进先出!)
父类与子类同名成员的处理:
- 子类对象可以直接访问到子类中同名成员
- 子类对象(在点后)加作用域可以访问到父类同名成员
继承同名静态成员处理方式:
静态成员特点:
静态成员变量:
①所有对象共享同一份数据 ②编译阶段分配内存 ③类内声明,类外初始化
静态成员函数:
①只能访问静态成员变量,不能访问非静态成员变量
②所有对象共享同一份函数示例
同名静态成员处理方式和非静态处理方式一样,只不过访问静态成员有两种访问的方式(通过 对象访问 和 通过类名访问)
多继承语法:
C++允许一个类继承多个类
语法:class 子类 :继承方式 父类1 , 继承方式 父类2...
多继承可能会引发父类中有同名成员出现,需要加作用域区分
菱形继承:
菱形继承概念:
两个派生类继承同一个基类
又有某个类同时继承者两个派生类
这种继承被称为菱形继承,或者钻石继承
菱形继承问题:
- 羊继承了动物的数据,驼同样继承了动物的数据,当草泥马使用数据时,就会产生二义性。
-
草泥马继承自动物的数据继承了两份,其实我们应该清楚,这份数据我们只需要一份就可以。
class Animal
{
public:
int m_Age;
};
//继承前加virtual关键字后,变为虚继承
//此时公共的父类Animal称为虚基类
class Sheep : virtual public Animal {};
class Tuo : virtual public Animal {};
class SheepTuo : public Sheep, public Tuo {};
void test01()
{
SheepTuo st;
st.Sheep::m_Age = 100;
st.Tuo::m_Age = 200;
cout << "st.Sheep::m_Age = " << st.Sheep::m_Age << endl;
cout << "st.Tuo::m_Age = " << st.Tuo::m_Age << endl;
cout << "st.m_Age = " << st.m_Age << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:
- 菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费以及毫无意义
- 利用虚继承可以解决菱形继承问题