c ++ двойное уведомление наблюдателя от отправки - PullRequest
2 голосов
/ 07 декабря 2011

Вот код, который я сейчас устраняю:

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? Похоже, он не получает правильную информацию о типе для выбора соответствующего вызова функции.

Спасибо за любую помощь!

1 Ответ

1 голос
/ 07 декабря 2011

CTimerNotification нужно read как-то так

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; в ITimerObserver.

...