C++ C++;无法理解crtp观察者模式设计
我正在尝试一个模板设计,允许automagic观察者/观察者功能。我有两个嫌疑犯负责这个问题:C++ C++;无法理解crtp观察者模式设计,c++,templates,crtp,C++,Templates,Crtp,我正在尝试一个模板设计,允许automagic观察者/观察者功能。我有两个嫌疑犯负责这个问题: 静态继承的发生方式与我在Observing::notify()上预期的不同 试图绑定到模板TYPE类中的enum类的TYPE::Status模板化参数 #包括 #包括 //观察器基类 模板 结构观测 { 模板 无效通知(状态); 受保护的: //仅通过继承构建 观察(){TYPE::subscribe(this);} ~s(){TYPE::unsubscribe(this);} }; //课堂观察
- 静态继承的发生方式与我在
上预期的不同Observing::notify()
- 试图绑定到模板
类中的TYPE
enum类的
模板化参数TYPE::Status
#包括
#包括
//观察器基类
模板
结构观测
{
模板
无效通知(状态);
受保护的:
//仅通过继承构建
观察(){TYPE::subscribe(this);}
~s(){TYPE::unsubscribe(this);}
};
//课堂观察
模板
可观测结构
{
静态空订阅(observer*obs){observer.insert(obs);}
静态无效取消订阅(观察*obs){obsers.erase(obs);}
静态std::设置观察器;
};
//可观察对象的观察者容器的静态定义
模板
std::set Observable::observators;
//可观察服务的实现
结构服务:可观察
{
枚举类状态{Up,Down};
无效广播(状态)
{
用于(观察*obs:观察者)
obs->notify(status);//据我所知,你想要实现的东西不起作用。在这段代码中,编译器只能在struct中找到一个notify
函数,它没有主体。因此链接器稍后会对此进行投诉
for (Observing<Service>* obs : observers)
obs->notify(status); // <--- unable to link `notify()`
用于(观察*obs:观察者)
obs->notify(状态);//notify(状态);
这个问题的答案(静态_cast的内容)只能在运行时获得——这就导致了动态多态性
因此,您必须尝试另一种解决方案:要么使用运行时多态性,要么更改类的体系结构。观察者模式的要点是主体不知道观察者的静态类型。您将需要virtual
。这意味着notify
不能作为模板,您需要修复Observable
的哪个成员表示要通知的参数
template <class TYPE>
struct Observing
{
using Status = typename TYPE::Status;
virtual void notify(Status status);
// ...
};
你说的无法链接
notify()```是什么意思?链接器在抱怨吗?你在std::set
中存储类型信息时丢失了类型信息,因此它将链接到Observing::notify
,而不是RealType::notify
,因为缺少类型信息。请改用虚拟函数,CRTP不适用于这种情况。
static_cast<To what?>(obj)->notify(status);
template <class TYPE>
struct Observing
{
using Status = typename TYPE::Status;
virtual void notify(Status status);
// ...
};
struct Process: Observing<Service>
{
void notify(Status status) override;
};