为何std::move后std::string对象打印地址不同?移动是否生效?
你混淆了对象地址和内部缓冲区地址
- 你打印的
&str和&s2是std::string对象自身在栈上的内存地址,这两个是完全独立的对象实例,栈地址肯定不一样,和移动操作本身没有关系。 - 移动操作的核心是转移对象内部管理的资源(比如存储字符串的堆内存缓冲区),不是让两个对象共用同一个栈地址。
- 要验证移动是否发生,应该打印它们内部缓冲区的地址,而非对象本身的地址。可以用
data()方法获取内部字符数组的指针。
修改后的验证代码:
#include <iostream> #include <string> void test1(std::string&& str) { // 打印str内部缓冲区地址 std::cout << "str内部缓冲区地址: " << static_cast<void*>(str.data()) << std::endl; std::string s2 = std::move(str); // 打印s2内部缓冲区地址 std::cout << "s2内部缓冲区地址: " << static_cast<void*>(s2.data()) << std::endl; // 打印移动后str的内部缓冲区地址(通常会变为空指针) std::cout << "移动后str内部缓冲区地址: " << static_cast<void*>(str.data()) << std::endl; // 对比对象本身的地址(本来就不同) std::cout << "str对象地址: " << &str << std::endl; std::cout << "s2对象地址: " << &s2 << std::endl; } int main () { test1("abc"); }
运行后你会看到:
s2的内部缓冲区地址和移动前str的地址完全一致,说明资源确实被转移了;而移动后的str内部地址通常会变成nullptr(不同标准库实现可能有差异,但原对象不再持有原来的资源)。
另外补充:std::move本身只是一个类型转换工具,把左值转成右值引用,它不会直接移动资源,真正的资源转移是在调用std::string的移动构造函数时完成的。
内容的提问来源于stack exchange,提问作者Sensiblewings47
相关产品推荐
相关产品推荐

