构造函数和析构函数

        c++利用构造函数和析构函数实现了对象所占内存的初始化和清空操作。对象的初始化和清除操作时强制执行构造函数和析构函数,如果没有自己实现,编译器提供默认构造函数和析构函数。

        构造函数作用于对象初始化,主要作用在创建对象时为对象的成员变量赋值,构造函数由编译器自动调用,不需要手动调用,当我们使用new时,会先使用malloc申请一块堆区空间,然后调用构造函数为申请的空间赋值。

        析构函数作用于对象销毁工作,清空对象所占有的堆区内存

注意:c++的一切操作都是在内存上的操作

构造函数

  • 在创建对象时自动调用,申请空间为成员变量赋值
  • 可以重载
  • 与类同名
  • 没有返回值
  • 如果没有实现构造函数,编译器会有一个默认的无参构造函数
  • 实例化对象

析构函数

  • 析构函数(~ 类名(){ })没有返回值
  • 函数名称与类名相同,但前面要有~
  • 析构函数没有参数,不可重载(构造函数可以重载)
  • 在对象被销毁之前自动调用析构函数(构造函数在创建对象时自动调用)

 

#include<iostream>
#include<string>
#include<Windows.h>
using namespace std;
class people {
public:
	people() {
		cout << "调用无参构造函数" << endl;
	}
	people(int a) {
		cout << "调用一个参数构造函数" << endl;
	}
	people(int a, int b) {
		cout << "调用两个参数构造函数" << endl;
	}
	~people() {
		cout << "调用析构函数" << endl;
	}
};
int main() {
	people p;//在栈区创建对象
	people *p1 = new people();//new在堆区创建对象
	people *p2 = new people(3);
	people *p3 = new people[2];//创建数组
	delete p1;//delete用于销毁new创建的空间
	delete p2;
	delete[]p3;//析构数组时,不delete会报错,准确来讲是有析构函数的数组必须delete[]
	system("pause");
	return 0;
}

<think>嗯,用户现在想了解C++构造函数析构函数的使用方法。我之前已经回答过关于C++数组赋值的问题,现在需要结合提供的引用内容来回答这个新问题。首先,我需要回顾用户提供的引用内容,看看有哪些相关的信息可以利用。 引用[1]提到了构造函数的不同形式,包括默认构造函数、带参数的构造函数,以及初始化列表。引用[2]详细说明了复制构造函数的特点,包括参数是同类对象的引用,以及编译器自动生成的情况。引用[3]讨论了构造函数析构函数的调用顺序,特别是全局对象局部变量的情况。引用[4]则展示了一个具体的类示例,演示了构造函数析构函数的调用过程,以及成员函数的使用。 接下来,用户的问题是关于构造函数析构函数的使用方法,我需要将这些引用内容整合起来,形成一个结构化的回答。应该包括基本概念、构造函数类型(默认、参数化、拷贝)、初始化列表、析构函数的作用,以及调用顺序的注意事项。此外,用户可能对实际应用场景或常见问题感兴趣,所以需要包含示例代码注意事项。 需要注意的是,用户可能对拷贝构造函数编译器自动生成的构造函数不太清楚,需要详细说明。同时,调用顺序的例子可以帮助他们理解对象生命周期。提供的引用中有关于全局对象局部变量析构顺序的例子,应该结合这些内容进行解释。 还需要检查是否有遗漏的重要点,比如移动构造函数(但用户提供的引用中没有提到,可能暂时不需要深入),或者析构函数在资源管理中的作用,比如释放内存等。根据引用中的例子,比如CPU类中的析构函数输出信息,可以强调析构函数用于清理资源。 最后,确保回答结构清晰,分点说明,并附上示例代码,帮助用户更好地理解。可能还需要生成相关问题,引导用户进一步学习,比如关于深浅拷贝、异常处理中的析构函数行为等。</think>### C++构造函数析构函数使用详解 --- #### 一、核心功能与基本规则 1. **构造函数** - **对象初始化入口**:在对象创建时自动调用 - **命名强制要求**:必须与类名完全相同(如`CPU::CPU()`) - **无返回值声明**:不写`void`或其他返回类型[^1] 2. **析构函数** - **对象销毁出口**:在对象生命周期结束时自动调用(如离开作用域/程序终止) - **命名规范**:`~类名`(如`CPU::~CPU()`) - **唯一性**:每个类只能有一个析构函数[^3] --- #### 二、构造函数类型与用法 1. **默认构造函数** 无参数或所有参数有默认值,未显式定义时编译器自动生成 ```cpp class CPU { public: CPU() { // 显式定义默认构造函数 cout << "构造了一个CPU!" << endl; } }; ``` 2. **参数化构造函数** 支持通过不同参数初始化对象状态 ```cpp class Time { public: Time(int h, int m, int s) { // 三参数构造函数 hour = h; minute = m; second = s; } }; ``` 3. **拷贝构造函数** 用同类对象初始化对象,未定义时编译器生成浅拷贝版本[^2] ```cpp class MyClass { public: MyClass(const MyClass& other) { // 显式定义拷贝构造函数 // 深拷贝逻辑 } }; ``` 4. **初始化列表**(高效初始化方式) 在构造函数参数列表后使用冒号初始化成员,**必须用于常量成员/引用成员** ```cpp class Point { const int id; int& ref; public: Point(int a, int& b) : id(a), ref(b) {} // 初始化列表 }; ``` --- #### 三、析构函数核心应用场景 1. **资源释放** 自动释放对象持有的资源(如动态内存、文件句柄) ```cpp class FileHandler { FILE* fp; public: FileHandler(const char* name) { fp = fopen(name, "r"); } ~FileHandler() { if(fp) fclose(fp); // 确保文件关闭 cout << "资源已释放" << endl; } }; ``` 2. **调试跟踪** 通过输出语句观察对象生命周期(如引用[4]中的CPU类示例) --- #### 四、调用顺序规则 1. **构造顺序** - 全局对象 > 静态对象 > 局部对象(按声明顺序) - 成员变量按类中声明顺序初始化(非初始化列表顺序) 2. **析构顺序** - 局部对象 > 静态对象 > 全局对象(与构造顺序相反) - 成员变量按声明逆序销毁[^3] ```cpp // 示例输出(引用[3]): // 时间 构造函数:8:0:0 (全局g_a) // 时间 构造函数:9:0:0 (全局g_b) // 时间 构造函数:10:10:10 (静态g_c) // 时间 构造函数:11:11:11 (静态g_d) // 进入main() // 退出main() // 时间 析构函数:11:11:11 (静态g_d) // 时间 析构函数:10:10:10 (静态g_c) // 时间 析构函数:9:0:0 (全局g_b) // 时间 析构函数:8:0:0 (全局g_a) ``` --- #### 五、关键注意事项 1. **隐式转换风险** 单参数构造函数可能引发隐式类型转换,可用`explicit`关键字禁止 ```cpp explicit Time(int h) { ... } // 禁止Time t = 5;这样的隐式构造 ``` 2. **动态内存管理** 类包含指针成员时,必须实现**深拷贝构造函数****析构函数** ```cpp class Buffer { char* data; public: Buffer(const Buffer& other) { data = new char[strlen(other.data)+1]; strcpy(data, other.data); } ~Buffer() { delete[] data; } }; ``` 3. **异常处理** 构造函数失败时应抛出异常,析构函数中**不要抛出异常**(可能导致资源泄漏) --- ### 示例代码解析(引用[4]) ```cpp CPU c1; // 调用默认构造函数,输出"构造了一个CPU!" CPU c2; // 再次调用,输出"构造了一个CPU!" c1.run(); // 调用成员函数 cout << c1.Rank(n);// 参数传递与返回值处理 c1.stop(); // 状态变更操作 // 程序结束前自动调用c2、c1的析构函数,逆序输出"析构了一个CPU!" ``` --- ### 相关问题 1. 如何防止对象被拷贝? 2. 构造函数抛出异常会导致内存泄漏吗? 3. 移动构造函数与拷贝构造函数的区别是什么? 4. 静态成员变量的初始化有什么特殊规则?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值