在c 11中为什么在std :: move之后没有权利使用移动变量?
因为std :: move(v)只是一个类似的演员
static_cast<T&&>(v) 其中T是v的类型.但是为什么移动的变量不是原始对象的引用? 例如,当o1“移动”到o2时,为什么我们不能再通过o1.str_访问o2的str_? #include <string> #include <iostream> struct MyClass { std::string str_; MyClass(MyClass const &) = delete; MyClass &operator=(MyClass const &) = delete; MyClass(MyClass &&o) : str_(std::move(o.str_)) {} MyClass(std::string const &str) : str_(str) {} }; int main(void) { MyClass o1 = MyClass("o1"); MyClass o2(std::move(o1)); std::cout << "o1: " << o1.str_ << "n" << "o2: " << o2.str_ << std::endl; return 0; } 输出: o1: o2: o1 更新: 看来,当我改变 MyClass(MyClass &&o) : str_(std::move(o.str_)) {} 至 MyClass(MyClass &&o) : str_(o.str_) {} 输出将是: o1: o1 o2: o1 那么根本原因是“std :: string”的举动?但为什么这会有所不同? 解决方法
让我们暂时忘掉你的类,并以std :: string为例.
std::string s1{"Hello,World!"}; // 1 std::string s2{s1}; // 2 std::string s3{std::move(s1)}; // 3 在第1行,您构建了一个std :: string对象.在第2行,你将s1复制到s2.现在s1和s2都将包含自己的字符串“Hello,World!”的副本.此副本由std :: string(或std :: basic_string< char>)的复制构造函数完成,该复制构造函数不修改参数. basic_string(basic_string const& other); 在第3行,您将s1的内容移动到s3.为此,首先将s1转换为std :: string&& (这是std :: move的作用).由于这个强制转换,调用现在将匹配std :: string的移动构造函数,而不是像前一行那样的复制构造函数. basic_string(basic_string&& other) noexcept; 这个构造函数,因为它始终使用字符串的rvalue实例调用,具有从参数中窃取资源的许可.因此,内部构造函数将简单地复制一些指针,这些指针指向由s1分配的内存以存储字符串,并设置s1实例的状态,使其现在为空.因此s3现在拥有该字符串. 在类实例中移动字符串数据成员时,会发生同样的事情.这就是为什么从std :: string对象移动时打印它时显示为空的原因. ?如果std :: string实现使用小字符串优化,则执行的操作会有所不同,但这只是一个实现细节.从概念上讲,两种情况都如上所述起作用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |