重点:
- 带多态性质的基类应该声明一个虚析构函数,如果类带有任何虚函数,它就应该拥有一个虚析构函数
- 类的设计目的如果不是作为基类使用,或者不是为了具备多态性,就不应该声明虚析构函数。
多态性质的体现:使用基类的指针(引用)去调用派生类的对象。如下:使用一个base指针,指向derived对象,然后delete base指针,想要调用派生类的析构函数。此时把base的析构函数设置为virtual,使用基类指针调用的时候发生了动态绑定,所以会调用派生类的析构函数,然后再调用基类的析构函数。
引入虚函数,会导致某一类中拥有了一个虚函数指针vptr,会带来额外的4B的内存消耗(在本机上),他会指向一个vtbl(virtual table虚表)。所以如果不是为了具备多态性,使用虚函数只会造成无畏的开销。
class base {
public:
base(int* _val) :val(_val) {}
virtual ~base() { delete val; cout << "基类析构函数调用<<endl"; }
int* val;
};
class derivedbase {
public:
//dericed(int* _val2) :base(_val2),val2(_val2) {} ---1
derived(int* _val2) :base(NULL),val2(_val2) {}
~derived()
{
delete val2;
cout << "派生类析构函数调用" << endl;
}
int* val2;
};
void main() {
int *p = new int (3);
base* pb = new derived(p);
delete pb;
}
这个程序一开始犯了个小错误,定义了如“---1”的派生类构造函数,此时用一个指针初始化基类指针val,和派生类指针val2.这样的结果就是:调用派生类的析构函数时候,已经把这块内存释放了,再调用基类析构函数,使得释放了一块已经不存在的内存,当然出错。(悬挂指针的错误)
来源:CSDN
作者:假老练啊哦
链接:https://blog.csdn.net/qq_34269988/article/details/89428619