Почему оператор перемещения не просто деструктор + конструктор перемещения - PullRequest
0 голосов
/ 15 января 2019

Учитывая следующий фрагмент:

class Foo
{
public:
    /* ... */
    Foo(Foo &&other);
    ~Foo();

    Foo &operator=(Foo &&rhs);

private:
    int *data;
};

Foo::Foo(Foo &&other)
{
    data = other.data;
    other.data = nullptr;
}

Foo::~Foo()
{
    delete data;
}

Foo &Foo::operator=(Foo &&other)
{
    if (this == &other) return *this;

    delete data;            /* SAME AS DESTRUCTOR */

    data = other.data;      /* SAME AS MOVE CONSTRUCTOR */
    other.data = nullptr;
    return *this;
}

Этот фрагмент - то, что я всегда получаю.

Зачем нам нужен оператор перемещения, если его поведение можно определить?
Если это утверждение неверно, то в каком случае оператор перемещения ведет себя иначе, чем просто деструктор + конструктор перемещения?

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Потому что не может быть выведено. Язык не знает, что означает разрушение вашего int*. Может быть, вам нужно заняться другими делами по дому.

На самом деле, если вы пишете конструктор перемещения, у вас обычно будет другая домашняя работа, потому что, если все, что вы делаете, это delete динамическая память, вы должны были использовать умный указатель и вообще не нужно будет писать свой собственный конструктор перемещения.

Кроме того, вы повторяете логику в своем коде. Вы можете «повторно использовать деструктор», избегая этих уловок в конструкторе и присваивателе перемещений, просто заменяя указатели вместо этого и позволяя деструктору объекта move-from делать то, что он обычно делает, когда придет время:

Foo::Foo(Foo&& other)
   : data(nullptr)
{
    *this = std::move(other);
}

Foo& Foo::operator=(Foo&& other)
{
    std::swap(this->data, other.data);
    return *this;
};

(Отказ от ответственности: вероятно, есть более идиоматический способ сделать это, что я не могу вспомнить, но вы понимаете.)

Теперь там гораздо меньше шаблонов. Таким образом, вы можете видеть, что даже если , если для вас выведенные на язык конструкторы перемещения, это вообще не будет включать деструктор.

0 голосов
/ 15 января 2019

С небольшими изменениями в вашем классе, может .

class Foo
{
public:
    /* ... */
    // deleted copy constructor and copy assignment
    // generated destructor, move constructor and move assignment

private:
    std::unique_ptr<int> data;
};
...