空用户定义的移动构造函数

时间:2018-01-07 14:19:55

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

我写的以下代码片段理解移动CTOR行为让我很难理解它的输出:

#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

海湾合作委员会版本:4.6.3

我的问题是关于标记为Doubt 2的行。不应该将地址打印为0吗?根据我的理解,正如我在class B中定义了一个空移动CTOR(标记为Doubt 1),它应该调用类Temp的默认CTOR(它不会被称为明显的从日志中)初始化其mp_Val类型的成员变量Temp

显然我缺少一些东西。

1 个答案:

答案 0 :(得分:4)

  

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

您的成员变量不是Temp类型,而是Temp *类型。你是对的,缺少初始化意味着该成员将被默认构造,并且类型Temp将涉及调用默认构造函数。但是,对于指针类型,默认构造会使对象保持未初始化状态。