【问题标题】:Strange behavior of run-time type information运行时类型信息的奇怪行为
【发布时间】:2015-03-21 11:49:35
【问题描述】:

我有两个班级 Base 和 Derived 是这样的:

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 Derived!

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

【问题讨论】:

  • 看起来像Typeid not functioning correcly的复制品,基本上如果你添加虚拟方法你会得到你想要的结果。
  • 如果你在写一个编译器,你会如何实现typeid?我可能会把它作为一个隐藏的虚拟方法来做。但是如果该类没有任何虚拟方法(因此没有 vtable),这是不可能的。我认为 C++ 规范是为了适应这一点而编写的。
  • 您将ptr 声明为Base*。你还有什么期待?它不像 Java 有运行时类型检查。 C++ 完全是静态的。
  • @texasbruce:当然,但是当Base 类至少有一个虚拟方法时,程序会给出预期的结果,这就是我的观点。

标签: c++ rtti typeid


【解决方案1】:

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

如果您要对此提出理由:它具有运行时成本(通常,每个对象中都有一个指向每个类元数据的指针,它支持虚拟调度和 RTTI),这将是一个如果你不得不为所有类型支付这个价格,无论你是否想在它们上使用 RTTI,这将是一种耻辱。

【讨论】:

    【解决方案2】:

    Too long for a comment.

    1) 引用表示类型类型的 std::type_info 对象。如果 type 是引用类型,结果引用引用的类型。

    2) 检查表达式表达式

    a) 如果表达式是泛左值 标识多态类型对象的表达式(即, 声明或继承至少一个虚函数的类), typeid 表达式计算表达式,然后引用 表示动态类型的 std::type_info 对象 表达。如果计算表达式的结果为空 指针,std::bad_typeid 类型的异常或派生自的类型 抛出 std::bad_typeid 。

    b) 如果表达式不是泛左值 多态类型的表达式,typeid 不计算 表达式,它标识的 std::type_info 对象表示 表达式的静态类型。左值到右值,数组到指针,或 不执行函数到指针的转换。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-27
      • 2013-08-30
      • 2023-04-03
      • 1970-01-01
      • 2016-02-29
      • 2014-10-23
      • 2011-03-13
      相关资源
      最近更新 更多