继承

image.png
派生类不能直接使用父类的private变量,需要调用继承下来的父类的共有函数(最好使用:: 作用域解析运算符)。

多态

C++的多态性:可以用基类的指针或者引用类型 指向 基类和派生类对象,而方法却根据对象类型而定,即多态性。
如果没有virtual:根据指针或者引用类型来决定调用哪个成员函数
如果加了virtual:运行时将会根据对象的实际类型来调用相应的函数

1:用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。 (返回值必须类型相同,除非在基类指针、引用和派生类指针、引用之间变换)
2:存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。
3:多态性是一个接口多种实现,是面向对象的核心,分为类的多态性和函数的多态性。
4:多态用虚函数来实现,结合动态联编(比如编译时只是声明变量一个基类指针,但是不知道具体对象是派生类还是基类,所以得运行的时候才能绑定具体使用哪个函数。如果没有使用虚函数,那么静态联编时直接按照指针或者引用类型进行绑定)
(备注:静态联编是在编译阶段解决了函数重载的问题,没到运行的时候就可以根据参数返回等确定,而虚函数不行,因为很可能参数一样,只是所属类不同。)
5:纯虚函数是虚函数再加上 = 0;
6:抽象类是指包括至少一个纯虚函数的类。
纯虚函数:virtual void fun()=0;即抽象类!必须在子类实现这个函数,即先有名称,没有内容,在派生类实现内容。

使用场景:
1.一个指针数组保存可能有基类可能有派生类,那么用基类指针类型创建数组,保存两种类,调用函数时,利用虚函数调用正确的函数。
2.一般析构函数采用虚函数,保证即使基类指针或者引用也不会导致销毁实例时调用错误的析构函数。

虚函数表里面保存的是函数的地址
每个类都有一个隐藏的指针vptr 指向 虚函数表,里面保存了所有的成员函数的地址,如果没有重新定义虚函数,那么这个函数的地址没有变,还是基类的虚函数的地址,如果重新定义了虚函数,那么更改为自己的,如果新加函数,则新加。

纯虚函数(抽象基类)

  1. class BaseEllipse{
  2. private:
  3. int a;
  4. int b;
  5. public:
  6. BaseEllipse(){}
  7. virtual ~BaseEllipse(){}
  8. int fun1();
  9. virtual double Area() const =0 ;
  10. }

函数声明结尾处用 = 0 则代表该类为纯虚函数,该基类不能实例化。