在c 11中为什么在std :: move之后没有权利使用移动变量?

在c 11中为什么在std :: move之后没有权利使用移动变量?,第1张

概述因为std :: move(v)只是一个类似的演员 static_cast<T&&>(v) 其中T是v的类型.但是为什么移动的变量不是原始对象的引用? 例如,当o1“移动”到o2时,为什么我们不能再通过o1.str_访问o2的str_? #include <string>#include <iostream>struct MyClass { std::string str_; MyC 因为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: 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之后没有权利使用移动变量?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1216196.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存