条款07:为多态基类声明virtual析构函数(悬挂指针)

不想你离开。 提交于 2019-12-07 07:24:21

 重点:

  1. 带多态性质的基类应该声明一个虚析构函数,如果类带有任何虚函数,它就应该拥有一个虚析构函数
  2. 类的设计目的如果不是作为基类使用,或者不是为了具备多态性,就不应该声明虚析构函数。

多态性质的体现:使用基类的指针(引用)去调用派生类的对象。如下:使用一个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.这样的结果就是:调用派生类的析构函数时候,已经把这块内存释放了,再调用基类析构函数,使得释放了一块已经不存在的内存,当然出错。(悬挂指针的错误)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!