运行-时间类型信息的奇怪行为

Strange behavior of run-time type information

我有两个 class BaseDerived 是这样的:

class Base
{
public:
};

class Derived : public Base
{
public:
};

和主要功能:

int main()
{
    Base* ptr = new Derived;

    std::cout << typeid(*ptr).name() << endl;

    delete ptr;

    system("pause");
}

程序输出显示 class Base,而我预计它会显示 class Derived。但是当我在 Base class 中添加一个虚拟方法时,现在输出显示 class Derived!

为什么 RTTI 至少需要一个虚拟方法?

Too long for a comment.

1) Refers to a std::type_info object representing the type type. If type is a reference type, the result refers to the referenced type.

2) Examines the expression expression

a) If expression is a glvalue expression that identifies an object of a polymorphic type (that is, a class that declares or inherits at least one virtual function), the typeid expression evaluates the expression and then refers to the std::type_info object that represents the dynamic type of the expression. If the result of the evaluated expression is a null pointer, an exception of type std::bad_typeid or a type derived from std::bad_typeid is thrown.

b) If expression is not a glvalue expression of polymorphic type, typeid does not evaluate the expression, and the std::type_info object it identifies represents the static type of the expression. Lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversions are not performed.

因此这种行为是预期的,因为在一种情况下 class 是多态的,而在另一种情况下则不是。

因为语言规范是这么说的。 RTTI 仅适用于多态类型;也就是说,具有虚函数的类型。对于其他类型,typeid returns 其参数的静态类型的类型信息。

如果您要为此寻求理由:它有 运行 时间成本(通常,每个对象中有一个指向每个 class 元数据的指针,它支持虚拟dispatch 和 RTTI),如果你必须为所有类型支付那个价格,无论你是否想在它们上使用 RTTI,那将是一种耻辱。