通过参考文章使用模板实现主题/观察者模式
template <class T>
class Observer
{
public:
Observer() {}
virtual ~Observer() {}
virtual void update(T *subject)= 0;
};
template <class T>
class Subject
{
public:
Subject() {}
virtual ~Subject() {}
void attach (Observer<T> &observer)
{
m_observers.push_back(&observer);
}
void notify ()
{
std::vector<Observer<T> *>::iterator it;
for (it=m_observers.begin();it!=m_observers.end();it++)
(*it)->update(static_cast<T *>(this));
}
private:
std::vector<Observer<T> *> m_observers;
};
我想知道而不是static_cast
,我应该使用dynamic_cast
?
这是因为如果我使用static_cast
,在下面的情况下我会得到编译错误。
class Zoo : public Observer<Animal> {
public:
Zoo() {
animal = new Bird();
animal->attach(this);
}
virtual ~Zoo() {
delete animal;
}
virtual void update(Animal* subject) {
}
Animal* animal;
}
// If using static_cast, compilation error will happen here.
class Bird : public Animal, public Subject<Animal> {
public:
virtual ~Bird() {
}
}
使用有没有副作用dynamic_cast
?
最好的肯定是根本不需要演员。你可以改变你的notify()
函数,以便它接受正确的参数:
void notify (T* obj)
{
std::vector<Observer<T> *>::iterator it;
for (it=m_observers.begin();it!=m_observers.end();it++)
(*it)->update(obj);
}
现在派生类可以传递正确的对象(this
,如果适用的话),而基类不需要知道派生类与T
.
按原样查看您的代码,static_cast
依赖于这样一个事实:无论源自Observer
,也将从作为模板参数传递的任何内容派生。我认为如果这不成立,它将在编译时被捕获,因为你不能static_cast
from this
to T*
.
但是,您的代码非常接近称为“奇怪重复模板模式”的模式。为了使其完美契合,请将派生类的类型传递给Observer
:
class Bird : public Subject<Bird> // note the template argument
现在你不需要从中派生Observer
's T
不再这样了,无论谁看到它(希望)都能识别该模式并更容易地理解代码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)