Простейшим способом реализации поведения, которое вы пытаетесь реализовать, будет использование std::optional
из C ++ 17. Это позволит вам «зарезервировать» память для вашего Object
без его создания и без использования кучи . Он также будет обрабатывать все вызовы конструктора и деструктора.
Это также можно сделать без std::optional
, но вам, по сути, придется реализовать подобное решение самостоятельно. В любом случае вам понадобится дополнительный член, чтобы указать, создан объект или нет, чтобы вы могли правильно обрабатывать уничтожение и присваивание.
Тогда ваш setObject
метод будет выглядеть примерно так:
void setObject(const Object& obj) {
if (constructed) {
*object = obj;
} else {
new (object) Object(obj);
constructed = true;
}
}
Чтобы использовать семантику перемещения, вы можете изменить свой метод следующим образом:
void setObject(Object obj) {
if (constructed) {
*object = std::move(obj);
} else {
new (object) Object(std::move(obj));
constructed = true;
}
}
Обратите внимание, что теперь setObject
принимает значение параметра по значению, поэтому его можно использовать как со ссылками lvalue, так и со значением rvalue для создания параметра, который затем будет перемещен в член.