满目山河空念远,落花风雨更伤春。 - 《浣溪沙·一向年光有限身》(晏殊)
2024.8.27
回答重点
C++中的std::move
是一个C++11引入的新特性,它的作用是实现移动语义。将对象的所有权转移给另一个对象,而不需要进行拷贝或移动操作,充分利用对象内部的资源,减少深拷贝,提高了性能。使用std::move
后,原对象会进入一个"移动后"的状态,这个状态下的对象可能处于未定义状态,因此不能保证其原有的功能。
原理:
move的实现本质就是:无论左值右值,都强转为右值返回。
// move
template <class T>
LIBC_INLINE constexpr cpp::remove_reference_t<T> &&move(T &&t) {
return static_cast<typename cpp::remove_reference_t<T> &&>(t);
}
作用
避免拷贝:当对象后续不再使用时,使用std::move
可以避免昂贵的拷贝操作,将内部资源转移出去。特别是对于大型对象或资源密集型对象,可以将昂贵低效的拷贝资源变为便宜高效的移动资源。减少了不必要的资源分配和释放,提高程序的执行效率。
使用示例
#include <vector>
#include <string>
#include <iostream>
int main() {
std::vector<std::string> v1 = {"Hello", "World"};
std::vector<std::string> v2;
// 使用std::move将v1中的元素移动到v2中
v2 = std::move(v1);
// 此时v1中的元素已经移动到v2,v1不应该再被使用
std::cout << "v2 contains:";
for (const auto& str : v2) {
std::cout << " " << str;
}
std::cout << std::endl;
return 0;
}
在这个示例中,v1
中的字符串被移动到v2
中,而不是进行拷贝。使用std::move
后,v1
不应该再被使用,因为它的状态是未定义的。
注意事项
- 使用
std::move
后,原对象不应该再被使用,除非它重新被赋值或构造。 std::move
并不会对对象做任何操作,它只是一个类型转换,告诉编译器这个对象我后续不再使用这个对象,可以对它使用移动构造函数或移动赋值运算符。- 在使用
std::move
时,需要确保对象的移动构造函数或移动赋值运算符是有效的,否则程序可能会失败。