我应该使用模板在主题观察者模式中的动态转换 [英] Should I use dynamic cast in the subject observer pattern with templates
问题描述
参考文章使用模板实现主题/观察者模式 p>
By referring to article Implementing a Subject/Observer pattern with templates
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
?
I was wondering instead of static_cast
, shall I use dynamic_cast
?
这是因为如果我使用 static_cast
,我将在以下情况下得到编译错误。
This is because if I am using static_cast
, I will get compilation error in the following case.
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() {
}
}
b $ b
使用 dynamic_cast
有任何副作用吗?
推荐答案
最好的一定是不必投降。您可以更改 notify()
函数,使其接受正确的参数:
The best would surely be not to have to cast at all. You could change your notify()
function so that it takes the right argument:
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
的关系。
Now derived classes can pass the right object (this
, if appropriate) without the base class needing to know the relation of derived classes to T
.
看看您的代码, static_cast
无论从 Observer
派生的任何东西都将从它作为模板参数传递的任何东西派生。我想如果这不会成功,它会在编译时被捕获,因为你不能来自
this
到 T *
。
Looking at your code as it is, that static_cast
relies on the fact that whatever derives from Observer
, will also derive from whatever it passes as a template argument. I think if this wouldn't hold, it would be caught at compile-time, because you couldn't static_cast
from this
to T*
.
但是,您的代码非常接近称为Curiously Recurring Template Pattern的模式。为了完美匹配,将派生类的类型传递给 Observer
:
However, your code is very close to a pattern known as the Curiously Recurring Template Pattern. For it to fit perfectly, pass the derived class' type to Observer
:
class Bird : public Subject<Bird> // note the template argument
现在你不需要派生自 Observer 的
T
,并且任何人(希望)能够识别模式并更容易理解代码。
Now you don't need to derive from Observer
's T
anymore and whoever looks at it (hopefully) recognizes the pattern and understands the code more easily.
这篇关于我应该使用模板在主题观察者模式中的动态转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!