1. 继承语法:class 子类:继承方式 父类
方式:公有继承,私有继承,保护继承
基类:
Class A
{
Public:
Int a;
Protected:
Int b;
Private:
Int c;
};
子类:
Class B : public A
{
Public:
Int a;
Protected:
Int b;
Private: // 不可访问
Int c;
};
Class B : protected A
{
Protected:
Int a;
Int b;
Private: // 不可访问
Int c;
};
Class B : private A
{
Private:
Int a;
Int b;
Private: // 不可访问
Int c;
};
1.1 私有成员只是被隐藏了,但还是会继承下去
1.2 父类中的所有非静态成员都会继承下去
1.3 继承中先调用父类的构造函数再调用子类的构造函数,析构顺序相反
1.4 子类中出现和父类同名的成员变量和函数,直接调用会调用子类的。如果想调用父类的,需要加父类的作用域。
1.5 子类中出现和父类中重名的函数,则覆盖掉父类的所有同名的函数(包括重载函数)。如果想调用父类的函数,需要加父类的作用域。
2. 菱形继承
2.1 菱形继承,子类会继承重复的数据。
2.2 利用虚继承可以解决菱形继承。
class animal
{
public:
int age ;
};
class Sheep : virtual public animal{};//继承时加virtual关键字,避免菱形继承
class Camel : virtual public animal{};//继承时加virtual关键字,避免菱形继承
class SheepCamel : public Sheep, public Camel{};
int main()
{
SheepCamel sc;
sc.Sheep::age = 30;
sc.Camel::age = 40;
cout << sc.Sheep::age << endl; //显示40, age只有一份
cout << sc.Camel::age << endl; //显示40, age只有一份
cout << sc.age << endl; //显示40, age只有一份
return 0;
}
3. 多态
3.1 静态多态:函数重载 和运算符重载,复用函数名
3.2 动态多态:派生类和虚函数实现运行时多态
3.3 静态多态和动态多态的区别:
静态多态的函数地址早绑定-编译阶段确定函数地址
动态多态的函数地址晚绑定-运行阶段确定函数地址
3.4 动态多态满足的条件:
有继承关系
子类重写父类的虚函数
3.5 使用动态多态:父类的指针或引用指向子类对象
4. 纯虚函数
在多态中,父类中的虚函数有时是没有意义的,主要调用子类重写的内容。因此可将虚函数改为纯虚函数。
语法:virtual 返回值类型 函数名 (参数列表) = 0;
当类中有纯虚函数,这个类也称为抽象类
抽象类特点:无法实例化。子类必须重写抽象类中的纯虚函数,否则也属于抽象类
5. 虚析构
多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用子类的析构代码。解决:将父类中的析构函数改为虚析构或纯虚析构
虚析构和纯虚析构的共性:可以解决父类指针释放子类对象。都需要有具体的函数实现。
虚析构和纯虚析构的区别:如果是纯虚析构,该类属于抽象类,无法实例化
语法: virtual ~类名(){}
Virtual ~类名() = 0;