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
的析构函数,确保资源能够被正确释放。
热门推荐
保健食品别当药吃!购买时认准这个标志
青蟹的美味诱惑,探索青蟹的多种烹饪方法
门的象征意义
果酸美容没那么简单
如何通过软件测试CPU好坏
巨菌草和中华粱草哪个更好?一文详解37种常见牧草特点
轻松上手,教你如何设置行车记录仪联网功能
借壳上市的风险及风险控制策略
房产转让办理房产证的详细流程与所需材料
恋爱焦虑症的表现及克服方法
Go语言是为了替代什么语言?
咖啡烘焙关键点详解:从回温点到一爆点的完美控制
《石灰吟》的诗意:于谦的高尚情操与人生追求
全球首创!托法替布治疗瘢痕疙瘩临床试验取得突破性进展
《启示录:兽的审判与灵魂的救赎》
如何在社交媒体上宣传家教:家教的有效策略
绿色发展绘底色 逐智向新谋振兴——来自老工业基地辽宁的高质量发展报告
瘀血肿胀如何快速消肿
财务管理新方向:6大趋势引领发展
棉花苗期如何使用甲哌鎓化控
人工养殖羊子的方法
螺旋藻片可以减肥吗
三角洲行动S3赛季医疗兵武器大揭秘!MP5还是P90,哪个才是战场之王?
美容服务智能推荐系统:个性化美丽方案的未来趋势
软银孙正义的人生轨迹,浓缩为八个关键启示
轻微食物中毒的表现症状有哪些
脚部早上出汗的原因是什么
李白送别友人,写了一首诗,送别诗的经典之作
银行的理财产品投资收益与投资者风险承受能力关系?
人口老龄化对经济及利率的影响