显式类型标识符与RTTI

Explicit type identifier vs RTTI

本文关键字:RTTI 标识符 类型      更新时间:2023-10-16

与RTTI相比,使用自己的类型标识符有什么优势吗?

例如

class A { virtual int mytype() = 0; };
class B : public A { int mytype() {return 1;} };
class C : public A { int mytype() {return 2;} };

它能更快吗?开销更少?还是应该在这种情况下始终使用RTTI?

测试RTTI之前,不要认为RTTI的开销会比您的解决方案更多/更少

您应该尝试两种解决方案,并衡量性能,以获得可靠的答案。

事实上,几年前我也问过自己同样的问题,最后我添加了一个成员变量来"加快"类型测试,就像你做的那样。事实证明,我的代码中充斥着不必要的愚蠢测试,而一些dynamic_cast<>本可以做同样的工作(事实上,做得更好)。

从那时起,我重构了代码以使用dynamic_cast<>,我不会再回头了。

需要注意的是:如果你的类是多态的,那么你已经为此"付费"了,所以只需使用dynamic_cast<>

使用自定义类型标识符的缺点(对于多态类型)是:

  1. 每个人都需要记录类继承。您需要分配的唯一整数或枚举值给定层次结构中的所有类
  2. 说出你的垂直继承就像A->B->D。对于A *p = new D;这样的情况,自定义类型标识将不允许将B*p匹配(即使它是有效的)

你需要意识到这些情况。另一方面,

  1. RTTI仅适用于多态类型(因此继承链不包含虚拟功能无法利用RTTI)
  2. 有一点表演RTTI导致的差异减少,如果真的对你来说很重要

但是,正如您在评论中提到的,对于较小的继承链,跟踪您自己的类型并没有坏处。例如

struct Base {
  enum TYPES { _BASE, _D1, _D2, _D3 };
  const TYPES &myType;
  Base (TYPES) : myType(_BASE) {}
};
struct D1 : Base {
  D1 () : Base(_D1) {}
};

http://en.wikibooks.org/wiki/C%2B%2B_Programming/RTTI

RTTI有一些局限性。首先,RTTI只能与多态类型一起使用。这意味着您的类必须至少有一个虚拟函数,可以直接使用,也可以通过继承使用。其次,由于存储类型需要额外的信息,一些编译器需要一个特殊的开关来启用RTTI。

所以,如果你需要它来处理没有虚拟函数的类,你就必须自己实现它。