首页 > 编程知识 正文

实变函数与泛函分析第二版,举例说明虚析构函数的作用

时间:2023-05-03 12:09:03 阅读:27191 作者:2126

我们知道,对象将在生命周期结束之前调用析构函数来完成所需的清理任务。 派生类调用的析构函数的顺序为“先子类、后基类”; 本文总结了在析构函数是普通析构函数、虚拟析构函数或纯虚拟析构函数的情况下,当使用delete运算符删除指针对象时,析构函数会发生什么情况。

析构函数CBase是基类,CDerive是其子类,类源代码如下:

class~cbase { public : cbase ((}//基类析构函数(cbase ) ) { cout 'CBase Destructor' endl; } private: int a; (; class~cderive 3360 public cbase { public : c derive () }//子类析构函数(c derive ) ) { cout 'CDerive Destructor' endl; }private: int b; (; 测试代码如下。

//case 1c derive * pderiveobj=newc derive (; delete pDeriveObj; //case2//基类指针对象可以指向派生类,表示基类与派生类赋值之间的兼容关系。 //但是,pBaseObj只能访问基类的成员,不能访问派生类的成员CBase* pBaseObj=new CDerive ()。 删除数据库obj; //等效于删除基本对象的测试结果:

/* case 1

构建子类: c驱动程序

后分辨率基类:CBase Destructor

/

/case2

仅限基类:CBase Destructor

*/

总结:

当delete运算符删除子类指针中的对象时,它将调用子类和基类的析构函数。 如果析构函数不为空,则即使基类指针指向子类对象,delete指针对象时也只会调用基类的析构函数。 如果析构函数基类的析构函数设置为虚函数,则delete基类指针对象可以根据实际类型清理对象。 源代码如下:

class cbase { public : cbase ((}//基类虚拟析构函数virtual ~CBase ) ) { cout 'CBase Destructor' endl; } private: int a; (; class c derive :公共库{ public : c derive () }//子类虚拟析构函数virtual ~CDerive ) { cout 'CDerive Destructor' endl }private: int b; (; 测试代码:

//基本对象CBase*pBaseObj_case1=new CBase (; delete pBaseObj_case1; //子类对象cbase * pbase obj _ case2=newc derive (; delete pBaseObj_case2; 执行结果:

//case1

CBase Destructor

//case2

CDerive Destructor -子类

CBase Destructor -基类

总结:

如果基类的析构函数是虚函数,则当基类指针指向子类对象时,使用delete运算符删除指针对象。 析构函数按照“先子类、后基类”的原则完成对象的清理。 这样多重继承的类可以确保每个类正确清理; 基类和子类的缓冲区将被释放

如果纯虚结构函数基类有纯虚函数,则基类无法实例化。 需要在子类中重写纯虚函数。 对于纯虚拟析构函数有点特殊,源代码如下:

class cbase { public : cbase ((}//基类析构函数virtual ~CBase ) )=0; 隐私: Int a; (; class c derive : public cbase { public : c derive (}//子类析构函数virtual ~CDerive ) { cout 'CDerive Destructor' endl; }private: int b; (; 测试代码:

CBase*pBaseObj=new CDerive (; 删除数据库obj; 编译代码时,您会发现编译代码不会成为提示。

“无法通过error LNK2019:分析的外部符号“public : virtual _ _ thiscall cbase 33603360~cbase (void )”? 1CBase@@UAE@XZ ),该符号是函数“public : virtual _ _ thiscallcderive 33603360~c derive (void )”? 1CDerive@@UAE@XZ (中引用)

这是因为需要调用子类析构函数,但发现代码中没有实现CBase析构函数,从而导致编译异常

解决方案是在CBase类外实现该函数体,而不是在子类中重写。 另外,~CDerive函数即使其函数名称不同,也是虚函数。 这和其他纯虚函数有特殊之处

必须在CBase类之外添加以下析构函数:

cbase :3360~cbase ((cout ' cbase destructor ' endl; }这样得到的运行结果如下。

CDerive Destructor -子类

CBase Destructor -基类

总结

最好将基类的析构函数声明为虚函数。 这将使所有派生类的析构函数自动成为虚函数。 这样,如果程序显式尝试使用delete运算符删除对象,而delete运算符的操作数使用指向派生类对象的基类指针,则会调用相应类的析构函数。

专业人员通常习惯于通过函数体显式定义空析构函数来声明虚拟析构函数,以便即使基类不需要析构函数,也能在撤销动态分配空间时得到正确处理。

参考资料:

33559 www.cn blogs.com/Jinxiang 1224/p/8468244.html

3358 c.biancheng.net/CPP/biancheng/view/247.html

3358 blog.csdn.net/y apian8/article/details/46418687

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。