C++移动赋值首先触发移动构造函数

标签 c++

#include <iostream>    

class C {

public:

  ~C() { std::cout << this << " destructor\n"; }

  C() { std::cout << this << " constructor\n"; }

  C(C&& rhs) {
    std::cout << &rhs << " rhs\n";
    std::cout << this << " move constructor\n";
  }

  C& operator=(C&& rhs) {
    std::cout << &rhs << " rhs\n";
    std::cout << this << " move assignment\n";
    return *this;
  }

};

C make_one() {
  C tmp;
  return tmp;
}

int main() {

  std::cout << "move constructor:\n";
  C c1(make_one());
  std::cout << &c1 << " &c1\n\n";

  std::cout << "move assignment:\n";
  C c2;
  c2 = make_one();
  ...
}

输出:

move constructor:
000000000021F9B4 constructor         // tmp constructed in make_one()
000000000021F9B4 rhs                 // return triggers tmp being passed to ...
000000000021FA04 move constructor    // ... c1's move constructor (see below)
000000000021F9B4 destructor          // tmp destructs on going out of scope
000000000021FA04 &c1                 // (confirmed c1's address)

move assignment:
000000000021FA24 constructor         // c2 constructed
000000000021F9B4 constructor         // tmp constructed in make_one() again
000000000021F9B4 rhs                 // tmp passed to ...
000000000021FA34 move constructor    // ... a new object's move constructor
000000000021F9B4 destructor          // tmp destructs on going out of scope
000000000021FA34 rhs                 // new object passed to ...
000000000021FA24 move assignment     // .. c2's move assignment operator
000000000021FA34 destructor          // new object destructs
...

移动赋值似乎首先触发移动构造函数并创建一个额外的对象。这是正常的吗?我希望(通过类比复制分配)将 tmp 直接传递给 c2 的移动分配。

[Visual Studio Express 2013]

最佳答案

“额外对象”称为返回值。从函数返回值时;该值是根据您提供给 return 语句的值复制/移动构造的。

这通常会经历复制省略,这可以解释为什么您不认识它。当发生复制省略时,C tmp; 行实际上会将 tmp 直接构建到返回值 中。复制省略也可能发生在其他一些情况下;有关全文,请参阅 C++11 [class.copy]#31。

大概是您在这里手动禁用了复制省略,或者编译器决定不执行复制省略是个好主意。 更新:您的编译器仅在发布版本上执行此特定的复制省略 - 感谢 Praetorian

关于C++移动赋值首先触发移动构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24666398/

相关文章:

c++ - 为什么 'for_each' 不读取函数对象

c++ - Visual Studio : how to start up a project without the console window poping up

c++ - 使用 Boost 处理流

c++ - 向由顶点构成的平面添加纹理

c++ - 在 C++ 中遍历不同类型的集合

c++ - sendto 和 recvfrom 在同一个程序中?

c++ - CMake zlib 在 Windows 上构建

c++ - char WM_KEYDOWN 在硬编码时显示为数字且没有大写字母

c++ - 如何打印类方法返回的值

c++ - 从成员函数返回字符串指针