1. 默认构造函数 (Default Constructor)
作用: 无参创建对象
签名: ClassName()
特点:
①无参数或所有参数都有默认值
②若未声明任何构造函数,编译器自动生成(空实现)
③用于容器默认初始化(如 vector(5))
调用时机:
Student s1; // 显式调用
Student* ps = new Student; // 动态分配
最佳实践:
class Student {
public:// 显式默认构造Student() = default;
};
2. 参数化构造函数 (Parameterized Constructor)
作用: 带参初始化对象
签名: ClassName(params)
特点:
①可带默认参数(Student(int age = 18))
②单参数构造函数可能引发隐式转换(用 explicit 禁止)
调用时机:
Student s("Alice"); // 直接调用
Student s = "Bob"; // 隐式转换(除非explicit)
最佳实践:
class Student {
public:explicit Student(std::string name) : name_(std::move(name)) {}
};
3. 拷贝构造函数 (Copy Constructor)
作用: 复制同类型对象
签名: ClassName(const ClassName& other)
特点:
①处理深拷贝(资源复制)
②编译器默认生成浅拷贝版本
③按值传参/返回时会调用
调用时机:
Student s1;
Student s2 = s1; // 拷贝构造
Student s3(s1); // 直接调用
最佳实践:
class Student {
public:Student(const Student& other) : name_(other.name_), age_(other.age_) {std::cout << "拷贝构造\n";}
};
4. 拷贝赋值运算符 (Copy Assignment Operator)
作用: 对象间赋值
签名: ClassName& operator=(const ClassName& other)
特点:
①处理已存在对象的赋值
②必须处理自赋值和资源释放
③返回 *this 支持链式赋值
调用时机:
Student s1, s2;
s1 = s2; // 拷贝赋值
最佳实践:
class Student {
public:Student& operator=(const Student& other) {if (this != &other) { // 检查自赋值name_ = other.name_;age_ = other.age_;}return *this;}
};
5. 移动构造函数 (Move Constructor)
作用: 高效转移资源所有权
签名: ClassName(ClassName&& other) noexcept
特点:
①C++11 引入,提升性能
②"窃取"源对象资源(如指针)
③应将源对象置于有效但可析构状态
调用时机:
Student createStudent();
Student s1 = createStudent(); // 移动构造(返回值优化)
Student s2 = std::move(s1); // 显式移动
最佳实践:
class Student {
public:Student(Student&& other) noexcept : name_(std::move(other.name_)), age_(std::exchange(other.age_, 0)) {std::cout << "移动构造\n";}
};
6. 移动赋值运算符 (Move Assignment Operator)
作用: 转移资源到已存在对象
签名: ClassName& operator=(ClassName&& other) noexcept
特点:
①高效转移资源,避免深拷贝
②必须处理自赋值
③标记 noexcept(影响容器操作)
调用时机:
Student s1;
s1 = Student("临时"); // 移动赋值
s1 = std::move(s2); // 显式移动赋值
最佳实践:
class Student {
public:Student& operator=(Student&& other) noexcept {if (this != &other) {name_ = std::move(other.name_);age_ = std::exchange(other.age_, 0);}return *this;}
};
完整示例代码
#include <iostream>
#include <string>
#include <utility>class Student {std::string name_;int age_ = 0;
public:// 1. 默认构造函数Student() = default;// 2. 参数化构造函数explicit Student(std::string name, int age = 18): name_(std::move(name)), age_(age) {std::cout << "参数化构造: " << name_ << "\n";}// 3. 拷贝构造函数Student(const Student& other): name_(other.name_), age_(other.age_) {std::cout << "拷贝构造: " << name_ << "\n";}// 4. 拷贝赋值运算符Student& operator=(const Student& other) {if (this != &other) {name_ = other.name_;age_ = other.age_;std::cout << "拷贝赋值: " << name_ << "\n";}return *this;}// 5. 移动构造函数Student(Student&& other) noexcept: name_(std::move(other.name_)), age_(std::exchange(other.age_, 0)) {std::cout << "移动构造: " << name_ << "\n";}// 6. 移动赋值运算符Student& operator=(Student&& other) noexcept {if (this != &other) {name_ = std::move(other.name_);age_ = std::exchange(other.age_, 0);std::cout << "移动赋值: " << name_ << "\n";}return *this;}~Student() {std::cout << "析构: " << (name_.empty() ? "[已移动]" : name_) << "\n";}
};int main() {std::cout << "=== 默认构造 ===\n";Student s1; // 默认构造std::cout << "\n=== 参数化构造 ===\n";Student s2("Alice", 20); // 参数化构造std::cout << "\n=== 拷贝构造 ===\n";Student s3 = s2; // 拷贝构造std::cout << "\n=== 拷贝赋值 ===\n";Student s4; s4 = s3; // 拷贝赋值std::cout << "\n=== 移动构造 ===\n";Student s5 = std::move(s4); // 移动构造std::cout << "\n=== 移动赋值 ===\n";Student s6;s6 = Student("Bob"); // 移动赋值std::cout << "\n=== 程序结束 ===\n";
}