Полагаю, я собираюсь получить полную информацию об этом (прочитайте до конца, прежде чем приступить к полному срыву), но ... при условии, что конструктор окон никогда не выдаст:
void MyClass::init()
{
obj::~Window(); // destroy the object
new (&obj) Window(...); // construct the object
};
Я, конечно, подчеркну требование не бросать конструктора, как будто он бросает, вы останетесь в очень грязной ситуации: деструктор MyClass
вызовет деструктор Window
независимо от того, является ли объект живым и ударил ногами или сломался из-за неудачной конструкции, и в последнем случае вы получаете неопределенное поведение.
Конечно, типичная вещь, таким образом, будет std::unique_ptr<Window>
, но у нас есть препятствие динамического распределения, когда ситуация явно не требует этого ...
Так что вам лучше использовать библиотеку: Boost.Optional .
class MyClass
{
public:
private:
boost::optional<Window> obj;
};
Синтаксический вызов похож на указатель:
obj->foo();
Но единственным преимуществом является то, что вы получаете разрушение / строительство на месте с более безопасной семантикой. Уничтожить легко:
// both call ~Window() if an instance had been constructed
obj.reset();
obj = detail::none_t();
Для построения используйте TypedInPlaceFactory . И для назначения тоже ... которое, конечно, сначала очищает предыдущий экземпляр (если есть):
void MyClass::init(Arg1 arg1, Arg2 arg2)
{
obj = boost::in_place<Window>(arg1, arg2);
}
Основным преимуществом является то, что если во время конструирования теперь возникает какое-либо исключение, объект optional
остается в состоянии unitialized
, что является вполне жизнеспособным, и, таким образом, вам не нужно бояться неопределенного поведения.
Так что в основном это похоже на динамически размещаемый объект, принадлежащий интеллектуальному указателю ... за исключением того, что магия заключается в том, что объект не выделяется динамически, что гарантирует те же характеристики, что и у "нормального" объекта:)
Я должен добавить, что препятствие, не подлежащее копированию, является одной из причин создания InPlaceFactory.