#c #design-patterns #observers
Вопрос:
Насколько эффективно я могу написать setScore (), не добавляя его на IObserver ? Есть ли что-то лучшее, чтобы добавить такой метод ? или какая-нибудь лучшая реализация, чем эта ? ПОЖАЛУЙСТА, ПОМОГИТЕ.
ObserverPattern.cpp:88:7: ошибка: «класс IObservable» не имеет члена с именем » setScore’
//interface
class IObserver
{
public:
virtual void update(int) = 0;
};
//interface
class IObservable
{
public:
virtual void subscribe(IObserver *) = 0;
virtual void unsubscribe(IObserver *) = 0;
virtual void notifyAll() = 0;
};
class CricketMatchScore : public IObservable
{
public:
CricketMatchScore()
: mScore (0)
{
}
void subscribe(IObserver * obj)
{
mObservers.push_back(obj);
}
virtual void unsubscribe(IObserver * obj)
{
auto iter = std::find(mObservers.begin(), mObservers.end(), obj);
if (iter != mObservers.end())
{
mObservers.erase(iter);
}
}
void notifyAll()
{
for (auto amp; item : mObservers)
{
item->update(mScore);
}
}
void virtual setScore(int score)
{
if (mScore != score)
{
mScore = score;
notifyAll();
}
}
private:
std::vector<IObserver*> mObservers;
int mScore;
};
class CricInfo : public IObserver
{
public:
void update(int score)
{
std::cout<<score<<std::endl;
}
};
int main()
{
IObserver * ob1 = new CricInfo;
IObserver * ob2 = new CricInfo;
IObservable * obl = new CricketMatchScore;
obl->subscribe(ob1);
obl->subscribe(ob2);
obl->setScore(20);
return 0;
}
Комментарии:
1. Зачем использовать
IObservable*
в качестве типа дляobl
, когда вы могли бы использоватьCricketMatchScore*
(или на самом делеCricketMatchScore
, поскольку здесь нет причин использовать динамическое распределение)?2. Спасибо тебе за ответ, Фред. Я как раз проходил через внедрение @ medium.com/@gayashanbc/… , так должны ли мы создавать интерфейсы в этом случае ? Будут ли они по-прежнему иметь смысл, если мы не будем использовать динамический полиморфизм и не будем пытаться сделать вещи универсальными ? Простите, если мои вопросы глупы. Спасибо.
3. Для того чтобы интерфейс работал с максимальной универсальностью, он должен был бы иметь виртуальные функции для всех функций, которые могут понадобиться его клиенту. Если клиентам нужно
setScore
,IObservable
нужноsetScore
. Альтернативой является уродство, когда клиентdynamic_cast
переходит к типу сsetScore
функцией, и как только клиенту нужно это сделать, попрощайтесь с претензиями на универсальность.4. Среди этих двух реализаций, что лучше и почему ????? thispointer.com/… Против medium.com/@gayashanbc/…
Ответ №1:
Полиморфизм/Переопределение функций работает только тогда, когда вы переопределяете функцию(виртуальную), написанную в базовом классе, чтобы вести себя по-другому в производном классе, но здесь setScore
она не объявлена в вашем базовом классе. Итак, полиморфизм здесь не сработает. Это ваш лучший выбор
CricketMatchScore* ob3 = new CricketMatchScore(); //you already used ob1 above, it's a conflicting declaration in your code
Комментарии:
1. Лучшим вариантом было бы
CricketMatchScore ob3;
. Нет необходимостиnew
и в дополнительном багаже, который он вообще приносит.2. Ладно, понял. Спасибо.