我有兴趣详细了解 C++ 中 RTTI 的优势和局限性。假设我有以下场景:
class C {};
class C0 : public C {};
class C1 : public C {};
...
void print(int id, C* c) {
if (id == 0) dynamic_cast<C0 *>(c)->print();
else if (id == 1) dynamic_cast<C0 *>(c)->print();
...
}
是否可以使用注册表模式实现上述示例?例如,使用这样的东西:
map<int, ?> registry;
void print(int id, C* c) {
registry[id](c)->print();
}
最佳答案
只要将 print
设为虚函数就可以很容易地解决这个问题。那么你可以简单地拥有:
void print(C* c)
{
c->print();
}
它会为所有派生类做正确的事情。
但是如果你想保持 print
是非虚拟的,那么正如你所认识到的,有一个问题是 registry[id](c)->print();
可以工作。映射的值类型是编译时事实,但您希望在运行时行为有所不同。
好吧,我可以想出一种方法来做到这一点……通过使用虚函数。您需要创建一个类作为 C
的包装器,派生版本与从 C
派生的类型相匹配。一些模板的使用可能会使这个处理起来比较体面。然后根据指向基的指针声明映射,但通过派生包装器进行填充。
但最终这需要更多的复杂性,并且提供的好处并不比首先将 print
本身虚拟化所能实现的更多。
关于C++ RTTI 注册表模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31258218/