按值返回的函数无法按预期工作

时间:2019-10-02 01:41:01

标签: c++ constructor

我是C ++新手。我了解到一个函数可以按值返回,但是在我的代码中它似乎无法正常工作。

#include "pch.h"
#include <iostream>

class B {
public:
  int* ip;
  B() : ip(new int(0)) {}
  //COPY CTOR
  B(B& other){
    ip = new int(0);
    *ip = *other.ip;

  }
  //MOVE CTOR
  B(B&& other) : ip(NULL){
    ip = other.ip;
  }
  B& operator=(B& other)
  {
    int* ptr = new int(0);
    *ptr = *other.ip;
    delete ip;
    ip = ptr;
  }
  B& operator=(B&& other)
  {
    int* ptr = new int(0);
    *ptr = std::move(*other.ip);
    delete ip;
    ip = ptr;
  }
  ~B() { 
    delete ip; 
    ip = NULL; 
  }
};

B CreateB()
{
    B b;
   *(b.ip) = 99;
   return b;
}
int main()
{
    B BObj(CreateB());
    std::cout << "B.ip=" << *BObj.ip << std::endl;
    system("pause");
    return 0;
}

我在调试模式下使用Visual Studio 2019,我进入CreateB()并发现创建了本地对象B.在“ return b;”处语句调试步骤移至Move Constructor B(B && other),我发现这是编译器优化。编译器没有使用Copy构造函数从本地B对象创建B对象,而是使用Move Constructor。但是,执行Move构造函数后,调试使我进入了析构函数〜B()。现在,函数返回给main的对象消失了。为什么编译器不使用Copy Ctor然后删除本地对象?谢谢!

1 个答案:

答案 0 :(得分:3)

  

为什么编译器不使用Copy Ctor然后删除本地对象?

因为,正如您所观察到的,它改用了move构造函数。调用move构造函数,然后销毁了本地对象。 (当对象超出范围时,即使该对象已移出,也会调用析构函数。)

销毁本地对象后,其ip成员指向的对象被删除。这通常是好的,除了被移动的对象指向相同的东西。您可能希望将自己的移动构造函数设置为other.ip某个有效值。 (我通常建议使用nullptr,但是您的类似乎假设ip永远不会为null。)

例如:

B(B&& other) : ip(other.ip){
    other.ip = new int(0);
}