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: o1o2: o1
那么根本原因是“std :: string”的举动?但为什么这会有所不同?
解决方法 让我们暂时忘掉你的类,并以std :: string为例.std::string s1{"Hello,World!"}; // 1std::string s2{s1}; // 2std::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实现使用小字符串优化,则执行的 *** 作会有所不同,但这只是一个实现细节.从概念上讲,两种情况都如上所述起作用.
总结以上是内存溢出为你收集整理的在c 11中为什么在std :: move之后没有权利使用移动变量?全部内容,希望文章能够帮你解决在c 11中为什么在std :: move之后没有权利使用移动变量?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)