C 11移动无效

c++11 move not take effective?

本文关键字:无效 移动      更新时间:2023-10-16

i测试了C 11移动功能,但没有有效。谁能告诉我为什么?谢谢。代码如下:

class Base {
  public:
   Base() { cout << "Base" << endl;}
   ~Base() { cout << "~Base" << endl;}
   Base(const Base& base) { cout << "Copy" << endl; }
   Base& operator=(const Base& base) {cout << "operator=" << endl;}
   Base(Base&& base) { cout << "move" << endl;}
   Base& operator=(Base&& base) { cout << "move=" << endl;}
};
Base b;
Base&& GetResult() {
  return std::move(b);
} 
int main() {
Base&& tmp = GetResult();
cout << &b << endl;
cout << &tmp << endl;
}

输出:

 Base
 0x6013a0
 0x6013a0
 ~Base

为什么不调用move copymove operator=?为什么地址是相同的?

要添加出色的现有答案,我相信这里的主要要点是std::move所做的。

std::move不移动。

它是 abymally 命名的。

它只会给您一个XVALUE,指的是您提供的任何东西;该XVALUE将绑定到LVALUE不会的RVALUE参考。这意味着将std::move 的结果提供给移动构造函数或移动分配运算符。但是,它不为您做,而您在这里不这样做。


给予对命名的强烈批评,您肯定有另一种建议
&ndash;用户2079303

这是一个很好的话题,但是C 的创建者建议std::rval,现代C 的建筑师之一建议std::rvalue_cast(即使您实际上得到了Xvalue(。

就个人而言,我认为std::moveable将是一个不错的中间立场。

为什么移动复制和移动操作员=不称为?

我假设通过"移动复制"您的意思是"移动构造函数"。移动分配运算符未调用,因为您永远不会使用分配运算符。

没有移动(也没有副本(,因为 Base&&参考(对特定的R值引用(。引用参考/指向对象 - 它们不包含对象的状态。初始化参考时,没有复制或移动对象。

为什么地址是相同的?

将操作员地址应用于参考时,您将获得引用对象的地址。

让我们忽略一分钟的移动语义,只考虑熟悉的C 98复制构造函数。给定以下代码,您期望什么输出?

class Base {
  public:
   Base() { cout << "Base" << endl;}
   ~Base() { cout << "~Base" << endl;}
   Base(const Base& base) { cout << "Copy" << endl; }
   Base& operator=(const Base& base) {cout << "operator=" << endl;}
};
Base b;
Base& GetResult() {
  return b;
} 
int main() {
  Base& tmp = GetResult();
  cout << &b << endl;
  cout << &tmp << endl;
}

当然,您希望呼叫Base默认构造器,然后是b的地址两次,然后是Base Destructor。原因是因为您仅构建一个Base实例,而永远不会复制它 - 您只使用引用。

,您的示例就是这样。您使用的是rvalue参考而不是lvalue参考,但要点是相同的 - 只有一个Base变量,并且没有复制或移动发生。如果您想见证动作语义的动作,则可以尝试这样的事情:

Base getBase() {
    return Base{};
}
int main() {
    Base tmp = getBase();
    Base other = std::move(tmp);
}

(从getBase()移出可能会由编译器优化,但您仍然应该看到第二个。(