Как устранить ошибку компиляции здесь - для шаблона наблюдателя в C ++?

0

Здесь я получаю следующую ошибку компиляции. Почему не может производный класс получить доступ к другому методу производного класса. Хотя этот метод является общедоступным. Я здесь смущен. Пожалуйста помоги.

/export/home/joshis1/Dropbox/Design_Patterns_UML/ObserverPattern/ObserverPatternProgram-build-desktop-Qt_4_8_4_in_PATH__System__Release/../ObserverPatternProgram/UpdateReceiver.h:43: ошибка: нет подходящей функции для вызова "IPublisher :: registerObserver (UpdateReceiver * const)

У меня есть класс издателя - Интерфейс -

class ISubscriber;

/** Interface **/


class IPublisher
{

public:
   virtual void registerObserver(ISubscriber *observer) = 0;
   virtual void unregisterObserver(ISubscriber &observer) = 0;
   virtual void notifyObserver() = 0;
   virtual void setBaudRate(int newBaudRate) = 0;
   virtual void setAspectRatio(int newAspectRatio) = 0;
   virtual void setVolumeLevel(int newVolume) = 0;
};

//////////////////////////////////////

class ISubscriber;

class UpdateManager: public IPublisher
{
 private:

    QList<ISubscriber *> subscribers;
    int m_baudRate;
    int m_aspectRatio;
    int m_volumeLevel;

  public:

    UpdateManager()
    {
        qDebug()<<"Update Manager --- Server/Subject Initialized";
        subscribers.clear();

    }

    virtual void registerObserver(ISubscriber *observer)
    {
        subscribers.append(observer);
    }

    virtual void unregisterObserver(ISubscriber *observer)
    {
        int index = subscribers.indexOf(observer);
        subscribers.removeAt(index);
        qWarning()<<"Removed the subscriber Index = "<<index;
    }

    virtual void setBaudRate(int newBaudRate)
    {
        m_baudRate = newBaudRate;
        notifyObserver();

    }

    virtual void setAspectRatio(int newAspectRatio)
    {
        m_aspectRatio = newAspectRatio;
        notifyObserver();

    }

    virtual void setVolumeLevel(int newVolume)
    {
        m_volumeLevel = newVolume;
        notifyObserver();
    }


    virtual void notifyObserver()
    {
#if 0
        foreach( ISubscriber observer, subscribers )
        {
            observer.update(m_baudRate,m_aspectRatio,m_volumeLevel);
        }
 #endif
    }


};

///////////////////

У меня есть наблюдатель -

/** Subscriber Interface **/
class ISubsrciber
{
   public:

    virtual void update(int baudRate, int AspectRatio, int VolumeLevel) = 0;

};

class UpdateManager;
class ISubsrciber;

#include "IPublisher.h"


class UpdateReceiver: public ISubsrciber
{
 private:
    int m_baudRate;
    int m_aspectRatio;
    int m_volumeLevel;
    int m_receiverNumber;


public:
   // static int updateReceiverTracker;

 /** Update Interface of the client **/

 void update(int baudRate, int AspectRatio, int VolumeLevel)
 {
     m_baudRate = baudRate;
     m_aspectRatio = AspectRatio;
     m_volumeLevel =  VolumeLevel;

     qDebug()<<"The following client number : "<< m_receiverNumber<< " got the update ";
     qDebug()<<"The baudRate is "<<baudRate;
     qDebug()<<"The AspectRatio is"<<AspectRatio;
     qDebug()<<"The VolumeLevel is"<<VolumeLevel;


 }

 /** Constructor -- and registers with the Server or Publisher or UpdateManager **/
 UpdateReceiver(IPublisher *updateManager)
 {
   //m_receiverNumber = UpdateReceiver::updateReceiverTracker++;

    updateManager->registerObserver(this);
 }


};
  • 0
    В ваших предварительных декларациях есть опечатка: сначала вы используете ISubscriber а затем ISubsrciber .
  • 0
    Не пытайтесь реализовать шаблон Observer самостоятельно. Это слишком сложно, чтобы сделать это правильно. Просто используйте библиотеку сигналов / слотов. Boost имеет один и libsigc ++ тоже хорошо работает.
Показать ещё 2 комментария
Теги:

4 ответа

1
Лучший ответ

Что касается сообщения об ошибке, то у вас нет метода (по крайней мере, в этом вопросе) с подписью, которую, по-видимому, ищет ваш код. У тебя есть:

virtual void registerObserver(ISubscriber *observer)
    {
        subscribers.append(observer);
    }

Ваш первый файл описывает ISubscriber но ваш второй файл наследуется от ISubsrciber (sic).

У вас есть опечатка в вашем файле. Перейдите на ISubscriber и вам повезет больше!

0

класс

class UpdateReceiver: public ISubsrciber   // wrong 
class UpdateReceiver: public UpdateManager // right

должен наследовать UpdateManager не ISubsrciber?

0

Ну, я вижу несколько проблем в вашем решении. Во-первых, у вас есть разные форвардные объявления для типа ISubscriber как я заявил в своем предыдущем комментарии. Это приводит к тому, что ваша программа не компилируется.

Эти два не обязательно совпадают.

virtual void registerObserver(ISubscriber *observer) {...}
class UpdateReceiver: public ISubsrciber {...}
                                 ^^^^

Во-вторых, ваша реализация notifyObserver также нуждается в переосмыслении. Но так как вы прокомментировали этот код, я оставлю это вам. Просто помните, что вы держите указатели на ISubscriber в своем списке подписчиков, когда вы пытаетесь выполнить итерацию/цикл над ним.

Также определение unregisterObserver не соответствует вашей декларации.

virtual void unregisterObserver(ISubscriber &observer) = 0;
virtual void unregisterObserver(ISubscriber *observer) {...}

НО я бы рассмотрел некоторые основные рефакторинги для вашего кода. На мой взгляд, вы не должны смешивать интерфейс шаблона Observer с логикой приложения.

Я думаю, что ваше решение должно выглядеть примерно так. Он не завершен и не использует ваши классы QT, но вы должны получить эту идею. См. Демонстрацию для запускаемого решения.

class ISubscriber {
public:
    virtual void update() = 0;
};

class Publisher {
    std::vector<ISubscriber*> m_observerList;
public:
    virtual void registerSubscriber(ISubscriber& observer);
    virtual void unregisterSubscriber(ISubscriber& observer);
    virtual void notifySubscribers();
};

class UpdateManager : public Publisher {
    int m_baudRate;
    int m_aspectRatio;
    int m_volumeLevel;
public:
    virtual void setBaudRate(int newBaudRate);
    virtual void setAspectRatio(int newAspectRatio);
    virtual void setVolumeLevel(int newVolume);

    int getBaudRate() const;
    int getAspectRatio() const;
    int getVolumeLevel() const;
};

class UpdateReceiver : public ISubscriber {
    UpdateManager& m_manager;
public:
    UpdateReceiver(UpdateManager& manager) : m_manager(manager) {
        m_manager.registerSubscriber(*this);
    }
    virtual void update() {
        // Process the new values
        m_manager.getBaudRate();
        m_manager.getAspectRatio();
        m_manager.getVolumeLevel();
    }
};

DEMO

0

здесь updateManager-> registerObserver (это); вы отправляете объект UpdateReceiver, пока он требует ISubscriber.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню