我有一个名为MyClass
的类,它被另一个类订阅。当某些事件发生时,MyClass
应通知订阅者。 我正在尝试为订阅者的类型使用模板。因为我不想让其他人(负责订阅者类(需要关心修改订阅MyClass
。 所以我在下面写了代码,
class MyClass {
public:
template<typename T>
void subscribeEvents(const T &controller)
{
m_subscriber = static_cast<T*>(m_subscriber);
m_subscriber = &controller;
}
void notifyPositionChanged(const long &position) const {
(m_subscriber)->onPositionChanged(position);
}
private:
void m_subscriber; // will be changed to array or something else
}
实际上,controller
对象有一个名为onPositionChanged
的方法。
但如您所知,它不是为这一行编译的。
(m_subscriber)->onPositionChanged(position);
现在我明白为什么这是一个错误,但问题是我不知道如何修改代码或更改我的设计。请让我知道我错过了什么和误解。提前谢谢。
您不需要为此使用模板。只需为订阅者使用基类即可。MyClass 在您的基类上运行
class ISubscribe {
public:
virtual void onPositionChanged(const long &position) = 0;
};
class MyClass {
public:
void subscribeEvents(ISubscribe *controller)
{
m_subscriber = controller;
}
void notifyPositionChanged(const long &position) const {
(m_subscriber)->onPositionChanged(position);
}
private:
ISubscribe *m_subscriber; // will be changed to array or something else
};
class SampleSubscriber : public ISubscribe {
public :
void onPositionChanged(const long &position) override{
...
}
};
void main() {
SampleSubscriber s;
MyClass m;
m.subscribeEvents(&s);
....
}
您需要为所有订阅者定义一个通用接口,然后将此接口用作m_subscriber的类型。野蛮地将您收到的任何参数强制转换为定义的类型只会导致未定义的行为。
使用std::function
:
class MyClass {
public:
template<typename CALLBACK>
void subscribeEvents(CALLBACK &&controller)
{
m_subscriber = std::forward<CALLBACK>(controller);
}
void notifyPositionChanged(const long &position) const
{
if (m_subscriber)
m_subscriber(position);
}
private:
std::function<void(const long&)> m_subscriber;
}
这为订阅者提供了想要订阅的内容的完全自由。例如:
there.subscribeEvents([this](const long &pos) { handlePosChange(pos); }