Здесь я получаю следующую ошибку компиляции. Почему не может производный класс получить доступ к другому методу производного класса. Хотя этот метод является общедоступным. Я здесь смущен. Пожалуйста помоги.
/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);
}
};
Что касается сообщения об ошибке, то у вас нет метода (по крайней мере, в этом вопросе) с подписью, которую, по-видимому, ищет ваш код. У тебя есть:
virtual void registerObserver(ISubscriber *observer)
{
subscribers.append(observer);
}
Ваш первый файл описывает ISubscriber
но ваш второй файл наследуется от ISubsrciber
(sic).
У вас есть опечатка в вашем файле. Перейдите на ISubscriber
и вам повезет больше!
класс
class UpdateReceiver: public ISubsrciber // wrong
class UpdateReceiver: public UpdateManager // right
должен наследовать UpdateManager не ISubsrciber?
Ну, я вижу несколько проблем в вашем решении. Во-первых, у вас есть разные форвардные объявления для типа 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();
}
};
здесь updateManager-> registerObserver (это); вы отправляете объект UpdateReceiver, пока он требует ISubscriber.
ISubscriber
а затемISubsrciber
.