1. 右值引用的本质与价值
在C++98时代,我们处理对象拷贝时常常面临性能瓶颈。比如一个包含动态内存的类对象,在进行值传递或返回时总会触发深拷贝操作。这种拷贝对于临时对象而言完全是资源浪费——因为临时对象很快就会被销毁。
C++11引入的右值引用(Rvalue Reference)正是为解决这类问题而生。语法上,右值引用用双&&表示(如T&&)。与左值引用不同,它专门绑定到即将销毁的临时对象上。这使得我们可以"窃取"临时对象的资源,而非进行昂贵的深拷贝。
关键理解:右值引用不是新类型,而是对现有引用系统的扩展。它让编译器能区分"可安全窃取资源"的临时对象。
2. 移动语义的实战解析
2.1 移动构造函数实现
传统String类的拷贝构造需要分配新内存并复制内容:
cpp复制String(const String& other) {
size_ = other.size_;
data_ = new char[size_ + 1];
memcpy(data_, other.data_, size_ + 1);
}
而移动构造则直接接管原对象资源:
cpp复制String(String&& other) noexcept {
size_ = other.size_;
data_ = other.data_; // 资源转移
other.data_ = nullptr; // 置空原指针
}
注意几个关键点:
noexcept声明对标准库容器优化至关重要- 必须将原对象置为有效但可析构状态
- 移动后原对象不应再被使用(除非重新赋值)
2.2 移动赋值运算符
与移动构造类似,但需处理自我赋值:
cpp复制String& operator=(String&& rhs) noexcept {
if (this != &rhs) {
delete[] data_; // 释放现有资源
data_ = rhs.data_;
size_ = rhs.size_;
rhs.data_ = nullptr;
}
return *this;
}
解锁全文
加入我们的会员,获取最新、最热、最精彩的开发者技术内容