问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C++程序设计基础:析构函数详解

创作时间:
作者:
@小白创作中心

C++程序设计基础:析构函数详解

引用
CSDN
1.
https://blog.csdn.net/qq_40071585/article/details/145918481

青少年编程与数学 02-010 C++程序设计基础 26课题、析构函数

课题摘要: 本文详细解析了C++中析构函数的定义、特点、使用示例及虚析构函数的概念。析构函数是类的特殊成员函数,名称为类名前加~,无返回类型和参数,用于对象生命周期结束时的资源清理。其特点包括唯一性、特定的自动调用时机(局部对象作用域结束、全局对象程序结束、动态对象delete时)以及可继承但不重写。示例中,Resource类展示了构造函数分配内存、析构函数释放内存的过程,以及局部和动态对象析构函数的调用。虚析构函数在基类中定义,确保通过基类指针或引用删除派生类对象时,派生类析构函数被调用,防止资源泄漏。


在C++中,析构函数是类的一个特殊成员函数,用于在对象生命周期结束时进行清理工作。以下是关于类的析构函数的详细解析:

一、析构函数的基本概念

  • 定义方式
*   析构函数的名称是在类名前加上波浪号(`~`)。例如,对于一个名为`Car`的类,其析构函数就是`~Car()`。
*   它没有返回类型,也不能带任何参数。例如,`~Car()`是正确的,而`void ~Car()`或`~Car(int)`都是错误的。
  • 作用
*   主要用于释放对象占用的资源,如动态分配的内存、打开的文件、网络连接等。当对象的生命周期结束时,析构函数会被自动调用。例如,如果一个类中有一个成员变量是指向动态分配内存的指针,析构函数可以释放这块内存,防止内存泄漏。

二、析构函数的特点

  • 唯一性
*   一个类只能有一个析构函数。这与构造函数可以重载不同。因为析构函数没有参数,所以无法通过参数列表来区分不同的析构函数。
  • 自动调用时机
*    **局部对象** :当局部对象的作用域结束时,析构函数会被调用。例如,在一个函数中定义了一个局部对象,当函数执行完毕,对象的作用域结束,析构函数就会被调用。
*    **全局对象** :当程序结束时,全局对象的析构函数会被调用。全局对象的生命周期从程序开始到程序结束,析构函数在程序即将结束时进行资源清理。
*    **动态分配的对象** :当使用`delete`操作符删除动态分配的对象时,析构函数会被调用。例如,通过`new`关键字创建的对象,需要用`delete`来释放,此时析构函数会执行清理工作。
  • 可以被继承但不被重写
*   析构函数可以被继承,派生类会继承基类的析构函数。但是,析构函数不能被重写。在多态的情况下,如果基类的析构函数是虚函数,那么通过基类指针或引用删除派生类对象时,会调用派生类的析构函数,从而保证资源能够被正确释放。

三、析构函数的使用示例

#include <iostream>
using namespace std;

class Resource {
private:
    int* data;

public:
    // 构造函数
    Resource(int size) {
        data = new int[size];
        cout << "Resource allocated." << endl;
    }

    // 析构函数
    ~Resource() {
        delete[] data;
        cout << "Resource deallocated." << endl;
    }
};

void testFunction() {
    Resource localResource(10);  // 局部对象,作用域结束时调用析构函数
}

int main() {
    testFunction();  // localResource的作用域在这里结束

    Resource* dynamicResource = new Resource(20);  // 动态分配对象
    delete dynamicResource;  // 使用delete调用析构函数

    return 0;
}

在这个示例中,Resource类有一个成员变量是指向动态分配内存的指针。在构造函数中分配内存,在析构函数中释放内存。testFunction函数中的localResource是一个局部对象,当testFunction函数执行完毕,localResource的作用域结束,其析构函数被调用。在main函数中,通过new创建了一个动态分配的对象dynamicResource,使用delete时会调用其析构函数来释放资源。

四、虚析构函数

  • 定义
*   在基类中将析构函数声明为虚函数,即在析构函数前加上`virtual`关键字。例如,`virtual ~BaseClass()`。
  • 作用
*   确保通过基类指针或引用删除派生类对象时,能够调用派生类的析构函数,从而避免资源泄漏。如果基类的析构函数不是虚函数,那么在这种情况下只会调用基类的析构函数,派生类的析构函数不会被调用,可能导致派生类中资源没有被释放。
  • 示例
#include <iostream>
using namespace std;

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

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

int main() {
    Base* ptr = new Derived();
    delete ptr;  // 会先调用Derived的析构函数,再调用Base的析构函数

    return 0;
}

在这个示例中,基类Base的析构函数是虚函数。当通过基类指针ptr删除派生类Derived的对象时,会先调用Derived的析构函数,再调用Base的析构函数,确保资源能够被正确释放。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号