C++ 双重调度观察器通知

c++ double dispatch observer notification

本文关键字:通知 观察 调度 C++      更新时间:2023-10-16

这是我目前正在排除故障的代码:

void CTimer::notify()
{
    std::vector<IObserver*>::iterator it;
    for(it=observers.begin();it!=observers.end();++it)
    {
        ITimerNotification* notification = new CTimerNotification(now());
        (*it)->readNotification(*notification);
    }
}
class CTimerNotification : public ITimerNotification
{
    public:
        CTimerNotification(const timeval& t)
        {
            time = t;
        }
    protected:
        timeval time;
    private:
        virtual ~CTimerNotification();
        virtual void read(const IObserver& o) const
        {
            o.update(*this);
        }
        virtual const timeval& getTime() const
        {
            return time;
        }
};
class IObserver
{
    public:
        virtual ~IObserver();
        virtual void readNotification(const INotification&) const=0;
        virtual void update(const INotification&) const=0;
};
class ITimerObserver : public IObserver
{
    public:
        virtual void update(const ITimerNotification&) const=0;
};
class TestObserver : public ITimerObserver
{
    public:
        virtual void readNotification(const INotification& n) const
        {
            n.read(*this);
        }
        virtual void update(const INotification& n) const
        {
            std::cout<<"???: TestObserver: update()!n";
        }
        virtual void update(const ITimerNotification& n) const
        {
            std::cout<< n.getTime().tv_sec << "." << n.getTime().tv_usec <<": TestObserver: update()!n";
        }
};

因此,代码运行,CTimer::notify()被调用,这会创建一个TimerNotification并通过readNotification()将其传递给观察者,而观察者又调用通知的read()方法,该方法最终调用观察者(希望(正确的update()方法。

最后一步是失败的。它调用 update(INotification&) 方法,而不是所需的 update(ITimerNotification&) 方法。

对于这种尝试的双重调度模式,我在这里错过了什么?它似乎没有获取正确的类型信息来选择适当的函数调用。

感谢您的任何帮助!

CTimerNotification需要一个这样的read

virtual void read(const IObserver& o) const {
    ITimerObserver* to = dynamic_cast<ITimerObserver*>(&o);
    if (to) {
        to->update(*this);
    } else {
        o.update(*this);
    }
}

你需要一个ITimerObserver using IObserver::update;.