Сбросить объект

В последнее время я часто сбрасываю объект, назначая ему новое значение с помощью operator=, Большинство моих занятий имеют copy constructor а также operator= определяется с помощью идиомы "копировать и менять". Что отлично работает в большинстве случаев, хотя и не так эффективно, как могло бы быть, но в большинстве случаев это не имеет значения. Есть один случай, когда это не работает. Это когда destructor должен быть вызван до constructor нового объекта.

Примечание: большинство классов, для которых я использую это, нельзя скопировать

class Foo
{
public:
    Foo() : m_i(0) {}
    Foo(int i) : m_i(i) {}

    Foo(Foo&& rhs);
    Foo& operator=(Foo rhs);
    friend void swap(Foo& lhs, Foo& rhs);

private:
    Foo(Foo& rhs) {}    // uncopyable object

    int m_i;
};

Foo::Foo(Foo&& rhs)
: Foo()
{
    swap(*this, rhs);
}

Foo& Foo::operator=(Foo rhs)
{
    swap(*this, rhs);
    return *this;
}

void swap(Foo& lhs, Foo& rhs)
{
    using std::swap;
    swap(lhs.m_i, rhs.m_i);
}

int main()
{
    Foo f(123);
    f = Foo(321);   // at one time both Foo(123) and Foo(321) exist in memory
}

Затем я научил, возможно, переписать operator= сначала вручную вызвать destructor а затем сделать swap (в этом случае rhs будет взят по константной ссылке). Однако этот ответ на stackOverflow заставил меня думать иначе.

Мне очень нравится operator= для сброса моих объектов, потому что код чистый и такой же, как для встроенных типов (например, int). Он также использует как код из constructor а также destructor, поэтому не нужно писать и поддерживать дополнительный код.

Итак, мой вопрос: есть ли способ достичь моей цели, чтобы сбросить мой объект с чистым кодом и без лишнего кода, который нужно написать, и уничтожить ли объект до создания нового?

2 ответа

Решение

По определению, если вы присваиваете новое значение старому объекту, новое значение было создано до того, как может произойти присвоение.

Ваш "старый объект" тоже не разрушен.

Так нет. Нет пути. И не должно: вы не должны переопределять "очевидное" поведение оператора присваивания.

Но здесь может помочь размещение нового, кроме тильды и экзотического синтаксиса конструкции, возможно, этот код подходит к "чистому":)

Foo old(a, b, c);
old.~Foo(); // explicit destruction
new (&old) Foo(d, e, f);

Если в конструкторе имеется код, который также должен вызываться оператором присваивания, поместите этот код в закрытую функцию-член и вызовите его как из деструктора, так и из оператора присваивания.

Ваш объект не будет разрушен (и вы не хотите, чтобы он был действительно), но он будет делать то же самое, что и деструктор.

Другие вопросы по тегам