【问题标题】:Empty user-defined move constructor空的用户定义的移动构造函数
【发布时间】:2018-01-07 14:19:54
【问题描述】:

我为理解移动 CTOR 行为而编写的以下代码 sn-p 让我很难理解它的输出:

#include <iostream>

class Temp
{
  public:

    Temp(){
      std::cout << "Temp DEFAULT CTOR called" << std::endl;
      mp_Val = nullptr;
    }

    Temp(int inp) { 
      std::cout << "Temp CTOR called" << std::endl;
      mp_Val = new int(inp); 
    }

    Temp(const Temp& inp) {
      std::cout << "Temp COPY CTOR called" << std::endl;
      mp_Val = new int(*inp.mp_Val); 
    }

    Temp& operator= (const Temp& inp) {
      std::cout << "Temp ASSIGNMENT OPER called" << std::endl;
      mp_Val = new int(*inp.mp_Val);

      return *this;
    }

    int* mp_Val;
};

class B
{
  public:

    B(){
      std::cout << "Class B DEFAULT CTOR" << std::endl; 
      mp_Val = nullptr;
    }
    B(int inp) { 
      std::cout << "Class B CTOR" << std::endl; 
      mp_Val = new Temp(inp);
    }

    B(const B& in) { 
      std::cout << "Class B COPY CTOR" << std::endl; 
      mp_Val = in.mp_Val;
    }

     B(B&& in){ 
      std::cout << "Class B MOVE CTOR" << std::endl; //Doubt: 1
    }

    Temp *mp_Val;
};

int main() {
  B obj1(200);
  B obj2 = std::move(obj1);
  auto temp = obj1.mp_Val;
  std::cout << "Obj1 B::Temp address: " << obj1.mp_Val << std::endl;

  std::cout << "Obj2 B::Temp address: " << obj2.mp_Val << std::endl; //Doubt: 2

  return 0;
}

输出:

Class B CTOR
Temp CTOR called
Class B MOVE CTOR
Obj1 B::Temp address: 0xd48030
Obj2 B::Temp address: 0x400880

GCC 版本:4.6.3

我的问题是关于标记为Doubt 2的行。地址不应该打印为0吗?据我了解,由于我在class B 中定义了一个空移动CTOR(标记为Doubt 1),它应该调用Temp 类的默认CTOR(从日志中可以看出它没有调用)来初始化它的成员Temp 类型的变量 mp_Val

显然我缺少一些东西。

【问题讨论】:

  • 在 obj1 上移动之后,obj1 死了。然而您的代码仍在使用它。
  • @Eljay 这不是移动构造函数在 C++ 中的工作方式。
  • @Eljay 移动后obj1 处于与之前完全相同的状态,因为移动 ctor 不会以任何方式修改其参数。
  • @Eljay obj1 还没有死,因为我在移动 CTOR 中没有做任何事情。
  • "应该调用类Temp"的默认CTOR"不,它不应该,因为mp_val是一个指针。如果mp_valTemp 类型的成员变量,它会这样。

标签: c++ c++11 move move-semantics move-constructor


【解决方案1】:

根据我的理解,由于我在 class B 中定义了一个空的移动 CTOR(标记为 Doubt 1),它应该调用类 Temp 的默认 CTOR(它没有从日志中明显调用)到初始化其成员变量mp_Val,类型为Temp

您的成员变量不是Temp 类型,而是Temp * 类型。没错,缺少初始化程序意味着该成员将是默认构造的,对于 Temp 类型,这将涉及调用默认构造函数。但是,对于指针类型,默认构造使对象未初始化。

【讨论】:

    猜你喜欢
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-01
    • 2015-03-07
    • 2015-07-19
    • 2011-05-22
    • 1970-01-01
    相关资源
    最近更新 更多