首页 > 其他分享 >虚析构函数

虚析构函数

时间:2024-03-14 14:33:57浏览次数:29  
标签:函数 基类 constructor Base 析构 派生类 虚析构

在C++中,不能声明虚构造函数,但是可以声明虚析构函数。语法为

virtual ~类名();

如果一个类的析构函数是虚函数,那么,由它派生而来的所有子类的析构函数也是虚函数。析构函数设置为虚函数之后,在使用指针引用时可以动态绑定,实现运行时的多态,保证使用基类类型的指针就能够调用适当的析构函数针对不同的对象进行清理工作。
简单来说,如果有可能通过基类指针调用对象的析构函数(通过 delete),就需要让基类的析构函数成为虚函数,否则会产生不确定的后果。

#include <iostream>
using namespace std;

class Base{
public:
    Base()   {cout<<"Base constructor"<<endl;}
    ~Base()  {cout<<"Base destructor"<<endl;}
};

class Derived:public Base{
public:
    Derived()  {p = new int(0);cout<<"Derived constructor"<<endl;}
    ~Derived()  {
        cout<<"Derived destructor"<<endl;
        delete p;
    }
private:
    int *p;
};

void fun(Base* b){
    delete b;
}
int main(){
    Base *b=new Derived();
    fun(b);
    return 0;
}

结果

Base constructor
Derived constructor
Base destructor

这说明,通过基类指针删除派生类对象时调用的是基类的析构函数,派生类的析构函数没有被执行,因此派生类对象中动态分配的内存空间没有得到释放,造成了内存泄露。也就是说派生类对象成员p所指向的内存空间,在对象消失后既不能被本程序继续使用也没有被释放。对于内存需求量较大、长期连续运行程序来说,如果持续发生这样的错误是很危险的,最终将导致因内存不足而引起的程序终止。
避免上述错误的有效方法就是将析构函数声明为虚函数:

class Base{
public:
    Base()   {cout<<"Base constructor"<<endl;}
    virtual ~Base()  {cout<<"Base destructor"<<endl;}
};

结果

Base constructor
Derived constructor
Derived destructor
Base destructor

这说明派生类的析构函数被调用了,派生类对象中动态申请的内存空间被正确地释放这是由于使用了虚析构函数,实现了多态。

标签:函数,基类,constructor,Base,析构,派生类,虚析构
From: https://www.cnblogs.com/uacs2024/p/18072784

相关文章

  • 通过构造函数实现属性赋值(含有具体例子)
    一、什么是构造函数?new关键字实际上是在调用一个方法,这个方法叫构造方法(构造器)调用构造器的时候,如果你的类中没有写构造器,那么系统会默认给你分配一个构造器,只是我们看不到罢了。可以自己显式的将构造器编写出来:构造器的格式:[修饰符]构造器的名字(){}构造器和方法的......
  • Python 向函数传递参数(小结)
    目录1、位置实参2、关键字实参3、形参默认值4、将队列的副本传入函数5、传递任意数量的实参6、传递任意数量的关键字实参1、位置实参调用函数时,传递参数的顺序与函数定义中的参数顺序一致。defperson(name,age):passperson('Marry',34)2、关键字实参调用......
  • Lua 如何在Lua中调用C/C++函数
    Lua调用C函数有两种方式程序主体在C中运行,C函数注册到Lua中。C调用Lua,Lua调用C注册的函数,C或者Lua得到函数的执行结果。程序主体在Lua中运行,C函数作为库函数供Lua使用。C++的代码如下如何在Lua脚本中调用这个C语言函数(add_function)?#include<QCoreApplication>#inclu......
  • shell脚本中main函数中$#获取不到脚本传入参数个数浅析
    Linux的shell脚本,有时候我们在运行shell脚本时会给脚本传入参数,出于逻辑上的严谨,在脚本中可能会做一些逻辑判断或处理,例如判断脚本传入参数的个数。一般我们会用$#获取传入参数的个数,假如,我们在shell脚本的main函数中去判断脚本传入参数的个数,类似如下所示:.........function mai......
  • 单据类型参数设置增加自定义参数并通过BOS标准函数调用
     1、BOS函数说明2、创建对应单据的【单据类型参数】,继承自【单据类型参数模版】。 3、在单据参数中绑定【单据类型参数对象】 4、参数设置设置对应参数 5、在BOS中调用标准函数进行使用。 ......
  • 【JavaScript】面试手撕柯里化函数
    ......
  • 详细分析Mysql中的LOCATE函数(附Demo)
    目录1.基本概念2.Demo3.实战1.基本概念LOCATE()函数在SQL中用于在字符串中查找子字符串的位置它的一般语法如下:LOCATE(substring,string,start)LOCATE()函数返回子字符串在主字符串中第一次出现的位置如果未找到子字符串,则返回0具体的参数如下:substring......
  • 函数(1)
    1,函数是什么(维基百科)函数名,返回值类型,函数参数 2,分为库函数和自定义函数A)C语言的库函数·IO函数(输入输出函数)·字符串操作函数·字符操作函数·内存操作函数· 时间/日期操作函数·数学函数……举例,,(1)strcpy的使用arr2后面的#####还存在,但是有\0故打印在\0......
  • 【Python从入门到精通】函数详解
     【上图来源于网络图片】WhydoPythonprogrammerspreferdarkmode? Becauselightattractsbugs.Python的简洁性和易读性,认为这是吸引Python程序员的原因。【Python从入门到精通】专栏课程:1、【Python从入门到精通】认识Python2、【Python从入门到精通】变量&......
  • 详解c++多态中的析构与构造函数
    首先简单介绍一下多态。多态是面向对象编程中的概念,它允许我们使用基类类型的指针或引用来调用派生类对象的方法。C++中实现多态主要依靠虚函数和动态绑定。那怎么使用多态呢?基类指针或引用指向派生类对象。在我学习过程中,这些概念耳熟能详,但是为什么要有多态呢,先看下面这......