如何避免使用模板类型的派生类进行多态性动态强制转换

How to avoid dynamic cast in polymorphism with derived class of template type

本文关键字:多态性 动态 转换 派生 何避免 类型      更新时间:2023-10-16

我有这个架构(简短版本):

class BaseBatch {
virtual ~BaseBatch(){};
};
template<class T>
class Batch : public BaseBatch
{
void draw(T* data) {
do something..
}
};
class BatchManager
{
private:
static std::vector<BaseBatch*> batches;
public:
template <class T>
static void placeData(T* data){
//Loop through the entire container
bool found = false;
for (auto&& b: batches())
if (b->get_type() == typeid(T)) {
dynamic_cast<Batch<T>*>(b)->draw(data);
found = true;
}
//If no bach found, create a new One
if (not found) {
batches.push_back(new Batch<T>);
}
}
};

问题是 placeData 函数每 1 次循环被调用多次(多次),我认为动态转换对性能来说是一个真正的痛苦,但无法弄清楚如何在不使用它的情况下解决这个问题。它真的有那么大问题还是我不应该打扰它并继续使用它?如果我应该避免它,你会有什么建议?谢谢

与其使用std::vector<Batch*>请使用std::unordered_map<std::type_index, std::unique_ptr<BaseBatch>>。要访问批处理,请使用batches.find(std::type_index(typeid(T))),然后将其static_castBatch<T>*static_cast没有运行时开销。若要创建新批处理,请使用std::type_index(typeid(T))作为键。

dynamic_cast的性能可能不是这里的问题。实际上,使用此解决方案调用typeid可能与dynamic_cast一样糟糕。真正的潜在收益是unordered_map的查找速度,而不是遍历谁知道有多大的vector的每个元素并尝试dynamic_cast