Функция, возвращающая значение, не работает должным образом - PullRequest
2 голосов
/ 02 октября 2019

Я новичок в 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. На «возврат б;»Оператор debug перешел к конструктору Move B (B && other), который, как я понял, является оптимизацией компилятора. Вместо использования конструктора Copy для создания B-объекта из локального B-объекта компилятор использовал Move Constructor. Однако после выполнения конструктора Move отладка привела меня к деструктору ~ B (). Теперь объект, возвращенный функцией main, исчез. Почему компилятор не использовал Copy Ctor, а затем удалил локальный объект? Спасибо!

1 Ответ

3 голосов
/ 02 октября 2019

Почему компилятор не использовал Copy Ctor, а затем удалил локальный объект?

Потому что, как вы заметили, он использовал вместо этого конструктор перемещения. Был вызван конструктор перемещения, затем локальный объект был уничтожен. (Деструкторы вызываются, когда объект выходит из области видимости, даже если этот объект был перемещен из.)

Когда локальный объект был уничтожен, то, на что указывал его член ip, было удалено. Обычно это хорошо, за исключением того, что перемещенный объект указывает на одно и то же. Возможно, вы захотите, чтобы ваш конструктор перемещения установил other.ip в какое-то допустимое значение. (Я бы обычно предлагал nullptr, но, похоже, ваш класс предполагает, что ip никогда не является нулевым.)

Например:

B(B&& other) : ip(other.ip){
    other.ip = new int(0);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...