У вас есть три решения этой проблемы:
Первое решение : заставить приложение создать shared_ptr, сделав его конструктор закрытым. Это то, что я бы порекомендовал сделать для любого класса, производного от enable_shared_from_this
class ApplicationModel : public Observer, public boost::enable_shared_from_this<ApplicationModel> {
private:
ApplicationModel(); // private constructor
MyObservableType mot;
public:
// an instance of this class can only be created using this function
static boost::shared_ptr<ApplicationModel> buildApplicationModel() {
return boost::make_shared<ApplicationModel>();
}
void setup() {
mot.addObserver(shared_from_this()) ;
}
};
Второе решение : измените дизайн кода.
Вы не должны просить ApplicationModel зарегистрироваться в Observable, а делать это самостоятельно. Таким образом, ApplicationModel
ничего не навязывает, но если его владелец хочет вызвать addObservable
, он должен создать shared_ptr. Это более или менее то, что называется внедрение зависимости .
class Application {
private:
boost::shared_ptr<ApplicationModel> model;
MyObservableType mot;
public:
void setup() {
model = boost::make_shared<ApplicationModel>();
mot.addObserver(model);
}
};
РЕДАКТИРОВАТЬ: Третье решение: использовать фиктивный shared_ptr, как это:
class ApplicationModel : public Observer {
private:
boost::shared_ptr<ApplicationModel> myself;
MyObservableType mot;
public:
void setup() {
mot.addObserver(myself) ;
}
ApplicationModel() {
myself = boost::shared_ptr<ApplicationModel>(this, [](ApplicationModel*) {});
}
~ApplicationModel() {
mot.removeObserver(myself);
assert(myself.unique());
}
};
Идея состоит в том, чтобы создать shared_ptr для this
и указать shared_ptr
не вызывать деструктор (здесь я использую пустую лямбда-функцию, но вы можете легко создать встроенную структуру). Это взлом, и вы не должны этого делать.