在C++中,构造函数和析构函数是类的重要组成部分,用于管理对象的生命周期和资源。以下是关键点的系统总结:
构造函数
作用
初始化对象,在创建对象时自动调用,负责设置初始状态和分配资源。命名与形式
- 与类同名,无返回类型。
- 可重载(多个不同参数的版本)。
- 示例:
class Car { public: Car(); // 默认构造函数 Car(int speed); // 参数化构造函数 };
类型
- 默认构造函数:无参数。若未定义任何构造函数,编译器会自动生成一个。
- 拷贝构造函数:用同类对象初始化新对象,形式为
Car(const Car& other)
。 - 移动构造函数(C++11):通过右值引用转移资源,形式为
Car(Car&& other)
。 - 委托构造函数:调用同类其他构造函数,减少重复代码:
MyClass() : MyClass(0) {} // 委托给带参数的构造函数
初始化列表
- 在构造函数体执行前初始化成员变量。
- 必须用于
const
成员或引用成员:Example(int a, int b) : x(a), y(b) {}
析构函数
作用
清理资源(如释放动态内存、关闭文件),在对象销毁时自动调用。命名与形式
- 类名前加
~
,无参数和返回值。 - 每个类只能有一个析构函数。
- 示例:
~Car() { /* 清理操作 */ }
- 类名前加
关键场景
- 动态内存管理:若类中有
new
分配的资源,需在析构函数中delete
:~String() { delete[] data; }
- 继承中的虚析构函数:基类析构函数应声明为
virtual
,确保正确调用派生类析构函数:class Base { public: virtual ~Base() {} // 虚析构函数 };
- 动态内存管理:若类中有
调用时机
- 构造函数:对象创建时(局部变量、
new
、临时对象等)。 - 析构函数:对象销毁时(作用域结束、
delete
、异常退出等)。
示例代码
#include <cstring>
class String {
private:
char* data;
public:
// 参数化构造函数
String(const char* str) {
data = new char[strlen(str) + 1];
strcpy(data, str);
}
// 拷贝构造函数(深拷贝)
String(const String& other) {
data = new char[strlen(other.data) + 1];
strcpy(data, other.data);
}
// 析构函数
~String() {
delete[] data;
}
};
int main() {
String s1("Hello"); // 调用参数化构造函数
String s2 = s1; // 调用拷贝构造函数
return 0; // s1和s2析构,自动释放内存
}
注意事项
默认生成的函数
若未定义,编译器会自动生成默认构造函数、拷贝构造函数、析构函数等。但默认拷贝构造函数是浅拷贝,可能引发问题(如双重释放内存)。深拷贝与浅拷贝
若类管理资源(如指针),需自定义拷贝构造函数和赋值运算符,实现深拷贝。虚析构函数
基类必须声明虚析构函数,确保通过基类指针删除派生类对象时,正确调用派生类析构函数。
通过合理使用构造函数和析构函数,可以确保对象的正确初始化和资源的安全释放,避免内存泄漏和未定义行为。