虚析构函数分析

来源:互联网 发布:百度地图经纬度数据库 编辑:程序博客网 时间:2024/06/02 02:30

在子类继承父类的时候,关于父类中的析构函数为什么得设置成为虚函数问题,一直困扰着我。在查阅了C++ primary 5 P552 后,大致对虚析构函数有了一定了解,在这里和大家分享一下。

其实主要原因是为了避免内存泄露,因为在继承关系中,允许父类的指针或者引用指向子类的对象。比如 

class A{

public:

//其他函数的定义

vitual void mark();

private:

//。。。。。

}

class B::public A{

public:

//其他函数定义

void mark() override;

private:

//。。。。

}

上面A为基类,B public继承自A,那么

 B b;

A *p=&b;

是完全成立的,并且在函数调用基类指针或者引用作为形参,在调用虚函数的时候,会发生动态绑定,因为基类的指针或者引用可以指向自身类对象,也可以指向子类的对象。

好了,下面进入正题,分析为什么虚析构函数会避免内存泄露问题。

同样引用上述代码,只加上析构函数,假定其析构函数不是虚函数,代码如下:

class A{

public:

//其他函数的定义

vitual void mark();

~A()=default;

private:

//。。。。。

}

class B::public A{

public:

//其他函数定义

void mark() override;

~B()=default;

private:

//。。。。

}

  B b;

A *p=&b;

delete p;

此时程序是使用积累的额指针指向派生类的对象,当delete时,本意是删除派生类对象。但是因为此时析构函数并不是虚函数,故不会发生动态绑定,

进行删去派生类对象的动作。程序会产生未定义行为,派生类对象也没有删除。

如果将析构函数设置为虚函数,代码如下:

class A{

public:

//其他函数的定义

vitual void mark();

virtual ~A()=default;

private:

//。。。。。

}

class B::public A{

public:

//其他函数定义

void mark() override;

~B()=default;

private:

//。。。。

}

  B b;

A *p=&b;

delete p;

此时因为基类的析构函数是虚函数,当delete p时,会发生动态绑定派生类的析构函数,从而删除派生类对象,避免了内存泄露问题。


原创粉丝点击