C++ 在将模板 class 函数传递给另一个函数后无法调用它
C++ Unable to call template class function after passing it to another function
我有一个 Observable 模板。
template<typename T>
class Observable {
public:
~Observable() {
observers.clear();
}
void registerObserver(const std::shared_ptr<Observer<T>> & observer) {
observers.push_back(observer);
}
void update(const T & record) {
for (auto &observer: observers) {
observer->update(record);
}
}
private:
std::list<std::shared_ptr<Observer<T>>> observers;
};
我的观察员也是从模板创建的:
class Observer {};
template<class T>
class Observer : public Observer {
public:
virtual void update(const T record) = 0;
};
我运行这样的:
auto cat = Cat()
auto catObservable = Observable<Cat>();
auto catObserver = std::shared_ptr<CatObserver>(); // CatObserver is a derived class from Observer<Cat>
observable.registerObserver(catObserver);
observable.update(cat);
此代码在调用 observer->update(record)
的 Observable
模板中的 运行 时间有段错误。修复它的唯一方法是像这样进行动态转换:
void update(const T & record) {
for (auto &observer: observers) {
std::shared_ptr<CatObserver> catObserver = std::dynamic_pointer_cast<CatObserver>(observer);
catObserver->update(record);
}
}
我想要不同类型的观察者,我能想到的唯一方法是使用一个大的 if 语句或 switch 语句来尝试对所有观察者执行 dynamic_pointer_cast。这感觉就像代码的味道。
我是 C++ 的新手,甚至不确定这种类型的问题是否广为人知,我在这里尝试做的只是一种反模式。
有什么想法吗?
您正在插入空指针并将其推送到列表中:
// catObserver is nullptr
auto catObserver = std::shared_ptr<CatObserver>();
确实,就像创建一个没有参数的原始指针一样,它将为空:
CatObserver* rawCatObserver{}; // null
要实际创建一个 CatObserver
,您必须调用 std::make_shared
,它将进行动态分配:
// returns an allocated shared pointer
auto catObserver = std::make_shared<CatObserver>();
I'm new to C++ and not even sure if this type of a problem is well known and what I"m trying to do here is just an anti-pattern.
此代码没问题,但使用 std::list
迭代这些代码时性能可能会受到影响。对于您的用例,std::vector
可能更好。就个人而言,我尽量避免使用 std::unique_ptr
,因为所有权更加明确。如果我可以用 std::function
和几个 lambda 表达式替换所有那些 类,我通常会倾向于那个。
我有一个 Observable 模板。
template<typename T>
class Observable {
public:
~Observable() {
observers.clear();
}
void registerObserver(const std::shared_ptr<Observer<T>> & observer) {
observers.push_back(observer);
}
void update(const T & record) {
for (auto &observer: observers) {
observer->update(record);
}
}
private:
std::list<std::shared_ptr<Observer<T>>> observers;
};
我的观察员也是从模板创建的:
class Observer {};
template<class T>
class Observer : public Observer {
public:
virtual void update(const T record) = 0;
};
我运行这样的:
auto cat = Cat()
auto catObservable = Observable<Cat>();
auto catObserver = std::shared_ptr<CatObserver>(); // CatObserver is a derived class from Observer<Cat>
observable.registerObserver(catObserver);
observable.update(cat);
此代码在调用 observer->update(record)
的 Observable
模板中的 运行 时间有段错误。修复它的唯一方法是像这样进行动态转换:
void update(const T & record) {
for (auto &observer: observers) {
std::shared_ptr<CatObserver> catObserver = std::dynamic_pointer_cast<CatObserver>(observer);
catObserver->update(record);
}
}
我想要不同类型的观察者,我能想到的唯一方法是使用一个大的 if 语句或 switch 语句来尝试对所有观察者执行 dynamic_pointer_cast。这感觉就像代码的味道。
我是 C++ 的新手,甚至不确定这种类型的问题是否广为人知,我在这里尝试做的只是一种反模式。
有什么想法吗?
您正在插入空指针并将其推送到列表中:
// catObserver is nullptr
auto catObserver = std::shared_ptr<CatObserver>();
确实,就像创建一个没有参数的原始指针一样,它将为空:
CatObserver* rawCatObserver{}; // null
要实际创建一个 CatObserver
,您必须调用 std::make_shared
,它将进行动态分配:
// returns an allocated shared pointer
auto catObserver = std::make_shared<CatObserver>();
I'm new to C++ and not even sure if this type of a problem is well known and what I"m trying to do here is just an anti-pattern.
此代码没问题,但使用 std::list
迭代这些代码时性能可能会受到影响。对于您的用例,std::vector
可能更好。就个人而言,我尽量避免使用 std::unique_ptr
,因为所有权更加明确。如果我可以用 std::function
和几个 lambda 表达式替换所有那些 类,我通常会倾向于那个。