我最近阅读了Head First设计模式。本书显示了Java相关代码。但是,我尝试将Java代码转换为C ++。在《观察者模式》一章中,我在转换某处时陷入困境。相关代码如下。
class Subject{ //Publisher
public:
virtual void registerObserver(ObserverPtr o) = 0;
virtual void removeObserver(ObserverPtr o) = 0;
virtual void notifyObservers() = 0;
};
using SubjectPtr = std::shared_ptr<Subject>;
订户类接口:
class Observer{
public:
virtual void update(double temp, double humidity, double pressure) = 0;
};
using ObserverPtr = std::shared_ptr<Observer>;
显示元素界面:
class DisplayElement{
public:
virtual void display() = 0;
};
using DisplayElementPtr = std::shared_ptr<DisplayElement>;
和CurrentConditionsDisplay
class CurrentConditionsDisplay : public Observer, public DisplayElement{
SubjectPtr m_weatherData;
double temperature;
double humidity;
public:
CurrentConditionsDisplay(SubjectPtr weatherData);
void update(double temperature, double humidity, double pressure);
void display();
};
using CurrentConditionsDisplayPtr = std::shared_ptr<CurrentConditionsDisplay>;
我的问题:
在CurrentCurrentConditionsDisplay类的构造函数中,我希望Publisher(Subject)注册CurrentCurrentConditionsDisplay。
//constructor
CurrentConditionsDisplay::CurrentConditionsDisplay(SubjectPtr weatherData) :
temperature(0),
humidity(0)
{
m_weatherData = weatherData;
/* How should I pass 'this' ? */
m_weatherData->registerObserver(???????); //parameter type is ObserverPtr.
}
由于参数类型为ObserverPtr,应该如何传递“指针”?
我建议使用工厂方法,例如:
std::shared_ptr<CurrentConditionsDisplay>
MakeCurrentConditionsDisplay(SubjectPtr weatherData)
{
auto res = std::make_shared<CurrentConditionsDisplay>(weatherData);
weatherData->registerObserver(res);
return res;
}
如果您坚持要在构造函数中执行此操作,则可以使用std::enable_shared_from_this
:
std::enable_shared_from_this
class CurrentConditionsDisplay :
public std::enable_shared_from_this<CurrentConditionsDisplay>,
public Observer,
public DisplayElement
{
SubjectPtr m_weatherData;
double temperature = 0;
double humidity = 0;
public:
explicit CurrentConditionsDisplay(SubjectPtr weatherData) :
m_weatherData(weatherData)
{
m_weatherData->registerObserver(shared_from_this());
}
void update(double temperature, double humidity, double pressure) override;
void display() override;
};
不能从构造函数中调用