- 虚函数是实现多态的基础,普通函数属于静态绑定,而虚函数属于动态绑定
- 虚函数是通过虚函数表来实现的,只要有虚函数则对应的**类(不是对象)**就有一个虚函数表
- 每个对象的头部都会有指针指向类的虚函数表,如果时多继承的话可能会有多个指针指向不同父类的虚函数表
分析语句:Parent *p = new Child(); delete p;
:
- 如果析构函数不是虚函数,则释放内存时会调用Parent的析构函数,这样可能会造成内存泄露;
- 如果析构函数是虚函数,则根据虚函数表会调用Child的析构函数,调用完之后调用调用Parent的析构函数,这样能确保内存都得到有效的释放;
详细流程分析请参见: C++带有虚函数的单继承类的构造过程探索
- 构造子类构造函数的参数
- 子类调用基类构造函数
- 基类设置vptr
- 基类初始化列表内容进行构造
- 基类构造函数体调用
- 子类设置vptr
- 子类初始化列表内容进行构造
- 子类构造函数体调用
根据带有虚函数的构造流程
章节的描述可以知道,构造函数执行时虚函数表都还没有初始化好,所以构造函数定义为虚函数是没有意义的,我们要调用构造函数创建对象时,必须要知道对象的准确类型。
可以调用,但是没有意义。 虚拟函数的意义在于父类的指针能够调用子类对象的函数,但是在基类的构造函数调用虚函数时子类还没有构建好,所以调用的是基类的函数;在基类的析构函数调用虚函数时子类已经释放,此时调用是比较危险的。
virtual void fun()=0;
含有纯虚函数的类为抽象类,抽象类不能实例化对象,但是可以定义指针,纯虚函数是接口,由子类实现。
虚继承可以防止多重继承产生的二义性问题。