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
的析构函数,确保资源能够被正确释放。
热门推荐
昏迷多久被判定为植物人?医学界的解答来了!
干细胞在七类神经系统疾病中的临床研究进展
10种春节氛围感装饰学起来,让过年更加年味十足仪式感满满!
企业自用车辆折旧年限的秘密
企业自用小型客车折旧年限解析
九华山自驾游攻略:路线规划、行程安排与注意事项全解析
中国患者超千万!《自然》子刊:治疗类风湿关节炎,如何才算“达标”?
牙刷的保质期一般是几年 牙刷怎么放是正确的
东莞为何盛产顶尖篮球运动员
省队、梯队、校队,三大球运动会搭建青少年人才交流平台
NBA的历史最佳战绩是73胜9负,那CBA的历史最佳战绩呢?
《喜羊羊与灰太狼之异国大营救》:皓月公主的家庭关系能否成功改编?
喜羊羊与灰太狼之异国大营救:皓月公主的家庭秘密
康平羊汤:一碗传承千年的暖心美味
简阳羊肉汤:一碗汤如何做成10亿级产业?
厨仟艺教你开家火爆羊肉汤馆
人生的意义是什么?从多个维度探寻生命的价值
苟字的读音与含义探讨:从字义到生活态度的反思
在垂钓过程中如何选择鱼线?
峨眉山:佛教文化与普贤菩萨的圣地
薛良全&王澄琳:峨眉山摄影秘籍
冬季峨眉山旅游攻略:金顶观日出必打卡
托拉塞米片正确的指导说明书
临床常用药呋塞米vs托拉塞米治疗心衰怎么选?干货满满!
风湿性关节炎的饮食与禁忌
酪氨酸含量高的食物
酪氨酸酶吃什么能补上来
为什么吃某些食物能让我心情愉悦?
提升多巴胺,助力快乐每一天
短视频成瘾伤害大脑实锤!做好这8点,提升多巴胺,保护专注力