我正在使用C ++和MFC(基于对话框)。
在我的主对话框中,我有一个名为memmory(unsigned short*
,模拟PLC内存)的对象和另一个名为test
的{{1}}类对象。
对象A
引用了memmory并且能够更改它。在主对话框中,有一些图表取决于memmory的值。
我的问题是:当对象test
更改memmory的任何值时,如何更新此图表?
我可以给对象test
一个对话框的引用,每当测试更改memmory时,只需调用一个对话框方法来更新图形。这是不可能的,因为对象test
(类test
)不能引用对话框(由于某种原因)。
另一个选择是设置一个计时器并每隔X毫秒重新执行一次图形,但这个选项对我来说似乎有点脏。
我认为对象测试可以在每次更改memmory时发送消息A
,但为了这样做,我需要对该对话框的引用,对吗?
我很感激任何想法。
答案 0 :(得分:0)
您可以将memmory封装在将接受M
类型接口的订阅者的类IMemmoryChanged
中。其中一个订户将是主对话框。界面可以具有抽象函数OnChange()
。您可以在主对话框中实现IMemmoryChanged
接口。
创建主对话框后,您可以创建M
对象并调用M.AddSubscriber(dialog)
M::SetMemmory(unsigned short value)
将更改私有memmory对象并通知其所有订阅者(其中一个订阅者是主对话框)。
因此,当测试A
调用M.SetMemmory
时,将通知主对话框。
答案 1 :(得分:0)
如果您可以修改测试类,一种可能的设计解决方案是使用模式"Observer"。通用方法是让您的Test
类继承IObservable
接口,为观察者订阅和取消订阅提供API。同时让你的图表类和你想知道的关于内存变化的任何类继承IObserver
接口,提供API来通知对象有关它的一些重要事件。
当观察到重要的变化时,p.e。它改变了PLC内存,你可以使用IObserver
API通知所有订阅的观察者。
您可以将您的Observable类设为"Singletone",以便为其提供全局访问权限。您还可以使用任何适当的STL容器将观察者列表存储在observable(Test
类)中。
重要的事情是不要忘记在析构函数时取消订阅观察者。除非您的可观察类能够尝试通知某些实际上不存在的对象。
你可以使用更简化的" Observer"如果需要,可以直接在类中使用具体方法,而不是使用接口。
答案 2 :(得分:0)
如果使用对话框::PostMessage(hwndDialog,...)
初始化类A
,则使用hwnd
时不需要对该对话框的引用。这意味着A类不需要#include
对话框类h文件。
答案 3 :(得分:0)
这里有一个Observer
模式的完整工作示例。这是一个简单的例子,它不是完美的,例如name
类的Observable
属性是一个设计
问题。
我可以帮助您更好地了解Observer
模式的工作原理。
#include <vector>
#include <iostream>
using namespace std;
class Observer
{
public:
Observer(){};
void notify(const char* name){
cout << "Notyification from: " << name << endl;
}
};
class Observable
{
public:
Observable(const char* name):name(name){};
// You can redefine in observable child classes the behaviour of notify_change.
virtual void notify_change(){
for (vector<Observer>::iterator it=observers.begin(); it != observers.end(); ++it)
{
(*it).notify(name);
}
}
inline const char* get_name() {return name;}
void register_observer(Observer obj){observers.push_back(obj);}
// You should add something like unregister_observer too.
private:
const char* name;
vector<Observer> observers;
};
class Boss: public Observer {
public:
Boss(){};
};
class Worker: public Observable {
public:
Worker(const char* name):Observable(name){}
void stop_working(){
notify_change();
}
};
int main()
{
Boss some_boss;
Worker some_worker("You");
some_worker.register_observer(some_boss);
some_worker.stop_working();
return 0;
}