抽象类 && 继承
- 抽象类:包含纯虚函数的类称为抽象类,继承层次结构的较上层。
- 作用:将有关的操作作为结果接口组织在一个继承层次结构中,由它来为派生类提供一个公共的根,派生类将具体实现在其基类中作为接口的操作。
- 继承:子类继承基类的成员及成员函数,不可以删除,可以(修改)通过虚函数重写基类的方法,可以(增加)新增对于子类的新方法,其中对于子类的子类也会继承基类
- 继承作用:减少重复代码,调用子类方法,灵活性,解耦
- 抽象类注意:纯虚函数的定义由派生类给出,如果只是继承基类的纯虚函数,没有定义,那么派生类仍然还是一个抽象类,抽象类是不能定义对象的。否则给出定义,成为建立对象的具体的类。
- C++多态性:同一个函数名或操作符在不同的对象上具有不同的行为。
虚函数
- 虚函数:可以让子类重写(也叫覆盖),在派生类中重新定义的成员函数。
- 调用子类的函数:参考
- 创建基类类型指针,通过将指针指向基类或某个派生类对象,调用派生类的函数。
- A *a = new B(); || B b(); A* a = & b;如果派生类中没有虚函数实现,调用基类的实现
- 区分继承中普通函数&&virtual的函数调用(决定调用的是基类还是派生类中的函数):
- 普通函数:根据指针或引用的类型,
- 声明为virtual的函数:其调用的对象的基本类型(指针指向的地址对于的对象)
- virtual关键字在派生类中不是必须的,因为重写始终是虚拟的。
关键字
-
override:如果派生类与基类虚函数的签名不一致,编译器就会报错。
-
final:如果不希望某个类被继承,或不希望某个虚函数被重写,则可以在类名和虚函数后加上 final 关键字,再被继承或重写,编译器就会报错。
纯虚函数:
- 基类中没有定义,编译器要求在派生类中必须予以重写以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。
- 作用:当不想为基类创建对象时
- 注意:继承类中重新声明函数
vptr(虚指针)和vtbl(虚表):
-
vtbl(虚表)中:在类的继承中,每一个class产生所有虚函数指针
-
vptr(虚指针):每一个类添加一个指针,指向虚表,因为指针存在,又会占用内存,
-
因为继承的原因,子类中虚表还有内存中的数据都会增加,包含基类的虚函数和数据
-
如何获取到类对象的虚函数表地址:(int*)&a,虚函数表第1个函数地址(int*)*(int*)(&a)虚函数表第2个函数地址(int*)*(int*)(&a) + 1
-
如何调用到类对象虚函数表地址:创建函数别名typedef void(*Fun)(void);名为fun的无参返回类型为void的函数指针,创建 指向函数指针类型 的指针Fun pFun = nullptr;指针指向 = (函数指针类型的)虚函数表第1个函数对象,调用函数pFun();