目录
- 一、默认构造函数(Default Constructor)
- 二、普通构造函数(General Constructor)
- 三、拷贝构造函数(Copy Constructor)
- 四、移动构造函数(Move Constructor,C++11)
- 五、委托构造函数(Delegating Constructor,C++11)
- 六、析构函数(Destructor)
- 七、综合示例:完整类设计
- 八、总结对比
- 九、最佳实践
C++中的构造函数和析构函数是面向对象编程的核心机制,它们管理对象的生命周期和资源。本文结合C++11及后续标准,深入解析默认构造函数、普通构造函数、拷贝构造函数、移动构造函数、委托构造函数及析构函数的核心特性和应用场景。
一、默认构造函数(Default Constructor)
定义:没有参数或所有参数均有默认值的构造函数。若未显式定义任何构造函数,编译器会自动生成一个空实现的默认构造函数。
特点:
- 用于初始化对象默认状态
- 自动生成的条件:类中无任何构造函数时
- 可手动禁用或显式声明(= default或= delete)
示例:
class MyClass {
public:MyClass() = default; // 显式声明默认构造函数MyClass(int x = 0) : value(x) {} // 带默认参数的构造函数
private:int value;
};
注意事项:
- 若存在其他构造函数,编译器不再自动生成默认构造函数
- 对于含有内置类型成员的对象,默认构造函数不会初始化成员变量(可能产生随机值)
二、普通构造函数(General Constructor)
定义:带参数的构造函数,用于初始化对象的特定状态。支持重载,可通过不同参数组合创建对象。
特点:
- 通过初始化列表高效初始化成员变量
- 支持多态初始化,例如std::string(“Hello”)
示例:
class Student {
public:Student(int id, const string& name) : m_id(id), m_name(name) {} // 初始化列表
private:int m_id;string m_name;
};
应用场景:
- 需要明确初始化逻辑时(如数据库连接需指定IP和端口)
- 避免成员变量未初始化导致的未定义行为
三、拷贝构造函数(Copy Constructor)
定义:通过已有对象初始化新对象,形式为ClassName(const ClassName& other)。默认实现为浅拷贝,需手动处理指针成员。
调用时机:
- 对象作为函数参数传递(值传递)
- 函数返回对象时
- 显式拷贝初始化(MyClass obj2 = obj1;)
深浅拷贝对比:
// 浅拷贝(默认危险行为)
class ShallowCopy {
public:int* data;ShallowCopy(int val) { data = new int(val); }~ShallowCopy() { delete data; } // 潜在双重释放
};// 深拷贝(安全实现)
class DeepCopy {
public:int* data;DeepCopy(const DeepCopy& other) {data = new int(*other.data); // 重新分配内存}
};
四、移动构造函数(Move Constructor,C++11)
定义:通过右值引用(&&)转移资源所有权,避免不必要的拷贝开销。
核心机制:
- 窃取临时对象或即将销毁对象的资源
- 将原对象指针置空避免重复释放
- 需标记为noexcept以支持STL容器优化
示例:
class String {
public:// 移动构造函数String(String&& other) noexcept : data(other.data), size(other.size) {other.data = nullptr; // 转移后置空原指针}
private:char* data;size_t size;
};
性能优势:
- 减少动态内存分配次数
- 在vector::push_back等操作中避免深拷贝
五、委托构造函数(Delegating Constructor,C++11)
定义:通过初始化列表调用同类其他构造函数,减少代码冗余。
规则:
- 必须通过初始化列表委托
- 禁止循环委托(如A委托B,B又委托A)
- 可结合参数默认值实现灵活初始化
示例:
class Rectangle {
public:// 主构造函数Rectangle(int w, int h) : width(w), height(h) {}// 委托构造:正方形初始化Rectangle(int size) : Rectangle(size, size) {}// 委托构造:默认初始化Rectangle() : Rectangle(0, 0) {}
};
六、析构函数(Destructor)
定义:对象生命周期结束时自动调用,用于释放资源,形式为~ClassName()。
关键特性:
- 不可重载(每个类唯一)
- 虚析构函数支持多态删除(virtual ~Base())
- 默认析构函数不处理动态内存
资源管理示例:
class FileHandler {
public:FileHandler(const string& path) { file = fopen(path.c_str(), "r"); }~FileHandler() { if(file) fclose(file); // 确保资源释放}
private:FILE* file;
};
注意事项:
- 含有指针成员的类必须自定义析构函数
- 析构顺序:派生类→成员对象→基类
七、综合示例:完整类设计
class AdvancedClass {
public:// 默认构造AdvancedClass() : data(nullptr), size(0) {}// 普通构造AdvancedClass(int s) : size(s), data(new int[s]{}) {}// 拷贝构造(深拷贝)AdvancedClass(const AdvancedClass& other) : size(other.size), data(new int[other.size]) {std::copy(other.data, other.data + size, data);}// 移动构造AdvancedClass(AdvancedClass&& other) noexcept : data(other.data), size(other.size) {other.data = nullptr;}// 委托构造AdvancedClass(int a, int b) : AdvancedClass(2) {data[0] = a; data[1] = b;}// 析构函数~AdvancedClass() { delete[] data; }private:int* data;int size;
};
八、总结对比
函数类型 | 语法特征 | 核心作用 | 性能影响 |
---|---|---|---|
默认构造函数 | ClassName() | 基础初始化 | 低 |
普通构造函数 | 带参数 | 定制化初始化 | 中 |
拷贝构造函数 | const ClassName& | 对象复制(深/浅拷贝) | 可能高(深拷贝) |
移动构造函数 | ClassName&& | 资源转移 | 高 |
委托构造函数 | 构造器链式调用 | 代码复用 | 无 |
析构函数 | ~ClassName() | 资源释放 | 关键 |
九、最佳实践
- Rule of Five:若自定义拷贝构造/赋值、移动构造/赋值、析构函数中的任意一个,建议显式定义全部五个。
- RAII原则:通过构造函数获取资源,析构函数释放资源。
- 移动语义优先:对临时对象使用std::move触发移动语义。
- 委托构造优化:减少重复初始化代码。
通过合理运用这些特性,可构建高效、安全的C++对象模型,尤其在资源管理、高性能计算等场景中体现关键价值。