问题一:哪些函数不能实现为虚函数
注:虚函数的条件:
虚函数能产生地址,存在vftable中
对象必须存在(vfptr->vftable->虚函数地址)
- 构造函数
- virtual+构造函数,错误
- 构造函数中调用虚函数,不会发生动态绑定(只发生静态绑定)
-
static
静态成员方法也不能加virtual
为什么需要虚析构
首先看如下例子:
#include <iostream>
#include <typeinfo>
using namespace std;
class Base
{
public:
Base(int data) :ma(data)
{
cout << "Base()" << endl;
}
~Base()
{
cout << "~Base()" << endl;
}
virtual void show() { cout << "Base::show()" << endl; }
//virtual void show(int) { cout << "Base::show(int)" << endl; }
protected:
int ma;
};
class Derive : public Base
{
public:
Derive(int data = 20) : Base(data), mb(data) ,ptr(new int(data))
{
cout << "Derive()" << endl;
}
~Derive()
{
delete ptr;
cout << "~Derive()" << endl;
}
void show() { cout << "Derive::show()" << endl; }
private:
int mb;
int *ptr;
};
int main()
{
Base* pb = new Derive(10);
pb->show(); // 动态绑定
delete pb;
return 0;
}
输出结果为:
Base()
Derive()
Derive::show()
~Base()
可以发现没有调用派生类的析构函数 ~Derive(),这将会导致内存泄漏.
这是因为析构函数不是虚函数,delete pb
时是静态绑定只调用基类的析构,而不回去调用派生类的析构。
解决方法
将基类析构设置为virtual
,此时派生类vftable
的虚函数就有&Derive::show()
和&Derive::~Derive()
.这样delete pb
时会发生动态绑定调用派生类析构,然后根据继承机制再调用基类析构。文章来源:https://www.toymoban.com/news/detail-432924.html
要点
- 虚析构函数,析构函数调用时,对象是存在的
- 基类的析构函数是
virtual
虚函数,则派生类的析构函数自动成为虚函数,虽然这两个析构不同名 - 什么时候基类的析构必须实现为虚函数?
答:基类指针(引用)指向堆上new
出来的派生类对象时, delete 基类指针,调用析构时必须发生动态绑定,否则导致派生类析构不会被调用,造成内存泄漏文章来源地址https://www.toymoban.com/news/detail-432924.html
到了这里,关于虚析构函数相关知识的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!