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

В последнее время я часто сбрасываю объект, назначая ему новое значение с помощью 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, поэтому не нужно писать и поддерживать дополнительный код.

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

1

Решение

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

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

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

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

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

Другие решения

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

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

1

По вопросам рекламы [email protected]