c++ - 如何创建 shared_ptr 的容器到抽象类
问题描述
我正在尝试在 C++ 中创建一个主题观察者系统,就像 C# 中的事件系统一样。观察者类:
template <class T>
class Observer {
int id;
public:
static int nextId;
Observer() : id(nextId++) {}
virtual void handleEvent(const T&) = 0;
virtual ~Observer();
};
学科类:
template<class T>
class Subject {
set<shared_ptr<Observer<T>>> observers;
public:
Subject() : observers() {}
void notify(const T&);
void addObserver(Observer<T>& );
void removeObserver(Observer<T>&);
Subject<T>& operator+=(Observer<T>&);
Subject<T>& operator-=(Observer<T>&);
Subject<T>& operator()(const T&);
};
问题是当我尝试实现时,addObserver
我不知道如何添加对集合的引用。
我知道make_shared<Observer<T>>
正在创建一个新实例,所以当我尝试make_shared<Observer<T>>(observer)
创建抽象类时出现错误:
错误:抽象类类型'Observer'的无效新表达式</p>
我试过shared_ptr<Observer<T>> observerPtr(observer)
了,但效果不佳:
错误:没有匹配函数调用 'std::shared_ptr >::shared_ptr(Observer&)'</p>
如何shared_ptr
从从抽象类派生的对象的引用中创建一个?
我想要实现的是让这个例子工作:
class TemperatureSensor : public Subject<int> {};
class AirConditioner : public Observer<int> {
static int nextId;
int id;
void onTemperatureChange(int temperature){
std::cout << "Air Conditioner #" << id << " got a report from TemperatureSensor, reading " << temperature << std::endl;
}
public:
AirConditioner() : Observer() {
id = (++nextId);
}
void handleEvent(const int& param) override {
onTemperatureChange(param);
}
};
int AirConditioner::nextId = 0;
int main(){
TemperatureSensor s;
AirConditioner a,b,c;
(((s += a) += b) += c);
s(42); // Should print:
// Air Conditioner #1 got a report from TemperatureSensor, reading 42
// Air Conditioner #2 got a report from TemperatureSensor, reading 42
// Air Conditioner #3 got a report from TemperatureSensor, reading 42
}
解决方案
要回答有关实现 addObserver 的问题,使其工作的最简单方法是将指针存储在容器中:
template<class T>
class Subject {
set<Observer<T>*> observers;
public:
Subject() : observers() {}
void addObserver(Observer<T>& o) { observers.insert(&o); }
根据您希望如何管理观察者对象的生命周期,您可以使用set<shared_ptr<Observer<T>>>
,但在这种情况下,您应该传递 的share_ptr<Observer<T>>
as 参数addObserver(shared_ptr<Observer<T>>& o)
。如果您必须使用addObserver(Observer<T>&)
接口并且希望“观察者”设置为共同管理观察者对象的生命周期,则可以使用 std::enable_shared_from_this 并使 Observer 成为 std::enable_shared_from_this 的子类。
希望这可以帮助。
推荐阅读
- c++ - C++,OpenCV,在尝试显示图像时出现此错误“OpenCV(4.3.0) 错误:断言失败 (size.width>0 && size.height>0)”
- vb.net - 如何使用 VB Application.DoEvent
- java - 如何在 JavaFX 中同时处理按键?
- c# - 动态 lambda 表达式 - 比较列表中的属性
位置 0,属性位于位置 1 - python-3.x - 会话中的列表始终显示为空 - 烧瓶
- python - Texthero TD-IDF 计算
- python - 如何合并两个相同长度的列表,并通过替换值来保留长度
- php - Backpack 如何路由 CSS 文件?
- assembly - 在 6502 组件中绘制位图
- python - 使用 F2PY 创建 Fortran 扩展模块,自定义签名文件和子例程存储在单独的 Fortran 文件中?