2

現在トラブルシューティング中のコードは次のとおりです。

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&)

この試行された Double Dispatch パターンが機能するために、ここで何が欠けていますか? 適切な関数呼び出しを選択するための正しい型情報を取得していないようです。

助けてくれてありがとう!

4

1 に答える 1

2

CTimerNotificationreadこのようなものが必要です

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

using IObserver::update;inが必要ですITimerObserver

于 2011-12-07T07:08:10.117 に答える