实现对象何时更改某些值

时间:2014-05-07 12:14:06

标签: c++ mfc

我正在使用C ++和MFC(基于对话框)。

在我的主对话框中,我有一个名为memmory(unsigned short*,模拟PLC内存)的对象和另一个名为test的{​​{1}}类对象。

对象A引用了memmory并且能够更改它。在主对话框中,有一些图表取决于memmory的值。

我的问题是:当对象test更改memmory的任何值时,如何更新此图表?

我可以给对象test一个对话框的引用,每当测试更改memmory时,只需调用一个对话框方法来更新图形。这是不可能的,因为对象test(类test)不能引用对话框(由于某种原因)。

另一个选择是设置一个计时器并每隔X毫秒重新执行一次图形,但这个选项对我来说似乎有点脏。

我认为对象测试可以在每次更改memmory时发送消息A,但为了这样做,我需要对该对话框的引用,对吗?

我很感激任何想法。

4 个答案:

答案 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;
}