1. 从Student类看拷贝与移动的本质区别
让我们从一个简单的Student类开始,这个类包含姓名和学号两个成员变量:
cpp复制class Student {
public:
std::string name;
int id;
// 构造函数
Student(const std::string& n, int i) : name(n), id(i) {
std::cout << "构造函数调用" << std::endl;
}
// 拷贝构造函数
Student(const Student& other) : name(other.name), id(other.id) {
std::cout << "拷贝构造函数调用" << std::endl;
}
// 移动构造函数
Student(Student&& other) noexcept
: name(std::move(other.name)), id(other.id) {
std::cout << "移动构造函数调用" << std::endl;
}
};
关键提示:移动构造函数必须标记为noexcept,这是STL容器使用移动语义的前提条件
当我们在main函数中执行以下操作时:
cpp复制Student s1("Alice", 1001); // 构造函数
Student s2 = s1; // 拷贝构造
Student s3 = std::move(s1); // 移动构造
控制台输出会清晰地展示三种构造方式的调用情况。这里std::move的作用仅仅是类型转换,它告诉编译器:"这个对象可以被移动,而不是拷贝"。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 左值引用与右值引用的本质解析
2.1 左值(lvalue)与右值(rvalue)
左值是指那些有明确存储位置、可以取地址的表达式,比如:
- 变量名(如s1)
- 返回左值引用的函数调用
- 前置自增/减运算(如++i)
右值是指临时对象、字面量等即将被销毁的值,比如:
- 字面量(如42、"temp")
- 算
