R值 参考行为

我一直在试图了解移动构造函数场景后面发生的事情,但在我的脑海中缺少一些东西。

   struct A {
     int s;
     A() : s(10) {}
     A(const A& o) : s(o.s) { std::cout << "copy contructor" << std::endl;}
     A(A&& o) : s(std::move(o.s)) {std::cout <<"move constructor" << std::endl;}
   };

   struct B  {
     std::string  s;
     B() : s("max") {;}
     B(const B& o) : s(o.s) {std::cout <<"copy contructor" << std::endl;}
     B(B&& o) : s(std::move(o.s)) {std::cout <<"move contructor" << std::endl;}
   };

   int main() {

   A a1;
   std::cout << " Before move " << " " << a1.s << std::endl;
   A a2 = std::move(a1); 
   std::cout << " After move" << " "  << a1.s << std::endl;

   B b1;
   std::cout << " Before move"  << " " << b1.s << std::endl;
   B b2 = std::move(b1);
   std::cout << " After move" << " "<< b1.s << std::endl;
   return 0;
 }

在一个对象上调用std::move,应该说明虽然对象在移动后还会存在,但我们很乐意清空”。

The output is 
Before move 10  
move constructor
After move 10

Before move max
move constructor
After move ""

我有两个问题。

1) 结构B的移动构造函数 “窃取 “了资源,让b1.s空着(“”)。对我来说,为什么a1.s没有发生这种情况,这是很有道理的,它看起来是复制而不是移动。

2) 如果我从结构B的移动构造函数中删除std::move。

 B(B&& o) : s(o.s) {std::cout <<"move contructor" << std::endl;}

我想应该是调用了一个复制构造函数。现在的输出是。

Before move max
move constructor
After move max

对我来说,这有部分意义 我完全理解了 “移动后资源最大”。现在看起来是一个拷贝,但没有任何 “拷贝构造函数 “的痕迹,应该用拷贝构造函数调用打印出来。

在我的脑海中肯定缺少了什么,谁能解释一下为什么?谢谢

解决方案:

  1. 从一个基元类型中移动与复制完全相同。只有在处理包含动态分配资源的对象时,移动才真正重要。例如,一个 std::string 将动态分配其字符串内容,这些内容将从原来的 std::string 到新的。

  2. 移动构造函数仍然是选择了由于 std::move 在这里。

    B b2 = std::move(b1);
    

    这句话 std::move(b1) 是一个r值,所以将选择移动构造函数来构造 b2. 改变移动构造函数的功能不会改变这一点。你所做的 改变的是,移动构造函数的行为与复制构造函数相同(除了它打印 “使用移动构造函数”)。因为你改变了 s(std::move(o.s))s(o.s),内部的字符串就会被复制过来。

给TA打赏
共{{data.count}}人
人已打赏
未分类

std::option类的实现

2022-9-10 6:58:40

未分类

PYQT Qcombobox设置值选择为一个变量。

2022-9-10 6:58:42

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索