C++ 观察者模式 - 坚持"Program to Interfaces"原则
C++ Observer Patterns - Sticking to "Program to Interfaces" principal
我正在c++中实现Head First Design Patterns中的Observer Pattern,并且我面临一个小问题。我得到了错误:"类主题没有名为setnewmeasurements的成员"行station->setNewMeasurments(0.5,10.0, 7.5);
似乎如果我想使用多态性,应该在接口("Subject")中定义方法"setNewMeasurments
"。但是这违背了"面向接口编程"的原则,而且我确实需要多态才能使观察者模式在这里工作。有什么意见吗?谢谢你! !
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
/**************************************************
*************** Interfaces ******************
***************************************************/
class Observer
{
public:
virtual void update(float temp, float humidity, float pressure) = 0 ;
};
class Subject
{
protected:
vector<Observer*> observers; //est-ce une bonne idée ici? c'est contraire au pattern strategy (separate changing elements from constant ones) -> Visiblement c'est ce qui est fait dans l'UML page 56
public:
virtual void registerObserver(Observer* o) = 0;
virtual void removeObserver(Observer* o) = 0;
virtual void notifyObserver() = 0;
};
class DisplayElement
{
public:
virtual void display() const = 0 ;
};
/**************************************************
************* Implementations ***************
***************************************************/
class WeatherData : public Subject
{
private:
float temperature;
float humidity;
float pressure;
public:
virtual void registerObserver(Observer* o){
observers.push_back(o); //y'a as un probleme la?
}
virtual void removeObserver(Observer* o){
std::vector<Observer*>::iterator position=std::find(observers.begin(), observers.end(), o);
if (position != observers.end())
observers.erase(position);
}
virtual void notifyObserver()
{
for (vector<Observer*>::iterator it=observers.begin() ; it!=observers.end() ; it++)
{
(*it)->update(temperature, humidity, pressure);
}
}
void measurmentChanged() {
notifyObserver();
}
void setNewMeasurments(float temp, float hum, float press)
{
this->temperature=temp;
this->humidity=hum;
this->pressure=press;
measurmentChanged();
}
};
class CurrentConditionsDisplay : public Observer, public DisplayElement
{
private:
float temperature;
float humidity;
float pressure;
Subject* weatherData;
// Faut penser à désallouer cette mémoire dans le destructeur --> exercice!! (le faire à la main puis utiliser le Wrapper)
public:
CurrentConditionsDisplay(Subject* w){
weatherData=w;
weatherData->registerObserver(this);
}
void update(float temp, float hum, float press){
temperature=temp;
humidity=hum;
pressure=press;
display();
}
void display() const {
cout << "Current Conditions Displayers " << endl << endl;
cout << "Temperature : " << temperature << endl;
cout << "Humidity : " << temperature << endl;
cout << "Pressure : " << temperature << endl;
};
};
int main()
{
Subject* station=new WeatherData;
CurrentConditionsDisplay mDisp(station);
station->setNewMeasurments(0.5,10.0, 7.5);
delete station;
system("PAUSE");
return 0;
}
这里的问题是,当你写:
Subject* station=new WeatherData;
你告诉编译器station
是一个Subject,而Subject没有定义一个叫做setNewMeasurments
的函数。
必须将指针station
转换为WeatherData
:
((WeatherData*)station)->setNewMeasurments(0.5,10.0, 7.5);
或在真正的c++中如CoffeeandCode所指出的:
static_cast<WeatherData*>(station)->setNewMeasurments(0.5,10.0, 7.5);
但是,由于WeatherDate
继承自Subject
,您可以直接写:
WeatherData* station=new WeatherData;
CurrentConditionsDisplay mDisp(station);
station->setNewMeasurments(0.5,10.0, 7.5);
这就是多态的工作方式!如果你声明一个对象为Subject
,你只能访问Subject
的函数和它的基类函数。
如果需要调用函数setNewMeasurments
,则需要通过将变量station
声明为WeatherData
来使其可访问。
我认为你实际上想要完成的是隐藏WeatherData
的实现,而不是整个类。您可以通过将函数实现移动到*.cpp文件中来实现这一点。因此,在*.h文件中只有函数定义,而在*.cpp文件中只有实际代码。
相关文章:
- "error: no matching function for call to"构造函数错误
- 调用专用模板时出错"no matching function for call to [...]"
- C++ Singleton - Prevent ::instance() to variable
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- Visual Studio Code "undefined reference to `WinMain@16'"
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 如何解决"invalid conversion from 'char' to 'const char*'"
- 使用 MATLAB 编码器生成C++代码:编译错误"undefined reference to `rgb2gray_tbb_real64'"
- 尝试链接我的着色器时,我收到错误代码"error c5145 must write to gl_position"
- Python str to C++ to Python str
- 为什么创建友元类的实例会导致"undefined reference to"错误?
- System.InvalidCastException - SQL to C++ - safe_cast<float>
- 使用 cmake 的 Linux 终端上的"Conversion to non-scalar type is requested"错误
- "no matching function for call to 'Vector::Vector'"错误
- vector<vector<double>> to mxArray using memcpy
- Tensorflow c++ api undefined reference to 'tflite::D efaultErrorReporter()'
- 当覆盖存在时调用基本虚拟"binded to object"函数
- OpenGL VBO Indexing ( How to compute Index Array)
- 为什么我会" void value not ignored as it ought to be"?
- C++ 观察者模式 - 坚持"Program to Interfaces"原则