C ++中的'typeid'与'typeof'

时间:2009-12-31 17:55:32

标签: c++ typeof typeid

我想知道C ++中typeidtypeof之间的区别是什么。这就是我所知道的:

  • typeid在C ++头文件type_info中定义的typeinfo文档中提到。

  • typeof在C的GCC扩展和C ++ Boost库中定义。

此外,这里是我创建的测试代码测试,我发现typeid没有返回我的预期。为什么呢?

的main.cpp

#include <iostream>  
#include <typeinfo>  //for 'typeid' to work  

class Person {  
    public:
    // ... Person members ...  
    virtual ~Person() {}  
};  

class Employee : public Person {  
    // ... Employee members ...  
};  

int main () {  
    Person person;  
    Employee employee;  
    Person *ptr = &employee;  
    int t = 3;  

    std::cout << typeid(t).name() << std::endl;  
    std::cout << typeid(person).name() << std::endl;   // Person (statically known at compile-time)  
    std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time)  
    std::cout << typeid(ptr).name() << std::endl;      // Person * (statically known at compile-time)  
    std::cout << typeid(*ptr).name() << std::endl;     // Employee (looked up dynamically at run-time  
                                                       // because it is the dereference of a pointer
                                                       // to a polymorphic class)  
 }  

输出:

bash-3.2$ g++ -Wall main.cpp -o main  
bash-3.2$ ./main   
i  
6Person  
8Employee  
P6Person  
8Employee

6 个答案:

答案 0 :(得分:165)

C ++语言没有typeof这样的东西。您必须查看某些特定于编译器的扩展。如果您正在谈论GCC的typeof,那么C ++ 11中通过关键字decltype会出现类似的功能。同样,C ++没有这样的typeof关键字。

typeid是一个C ++语言运算符,它在运行时返回类型标识信息。它基本上返回一个type_info对象,该对象与其他type_info对象具有相同的可比性。

注意,返回的type_info对象唯一定义的属性是它是相等的和不相等的,即描述不同类型的type_info个对象应该比较不相等,而{ {1}}描述相同类型的对象必须比较相等。其他一切都是实现定义的。返回各种“名称”的方法不能保证返回任何人类可读的内容,甚至不能保证返回任何内容。

另请注意,上述内容可能暗示(尽管标准似乎没有明确提及),type_info对同一类型的连续应用可能会返回不同的typeid个对象(其中,当然,还是要比较平等)。

答案 1 :(得分:40)

两者之间的主要区别在于以下

  • typeof是一个编译时构造,它返回编译时定义的类型
  • typeid是一个运行时构造,因此提供有关值的运行时类型的信息。

typeof参考:http://www.delorie.com/gnu/docs/gcc/gcc_36.html

typeid参考:https://en.wikipedia.org/wiki/Typeid

答案 2 :(得分:26)

typeid可以在运行时运行,并返回一个描述对象运行时类型的对象,该对象必须是一个指向具有虚方法的类对象的指针,以便RTTI (run-time type information)成为存储在课堂上。如果没有给出具有运行时类型信息的类的指针,它还可以给出表达式或类型名称的编译时类型。

typeof是一个GNU扩展,在编译时为您提供任何表达式的类型。例如,在声明可用于多种类型的宏中的临时变量时,这可能很有用。在C ++中,通常使用templates代替。

答案 3 :(得分:20)

回答其他问题:

  

我的以下测试代码是针对typeid做的   不输出正确的类型名称。   怎么了?

没有任何错误。您看到的是类型名称的字符串表示形式。标准C ++不会强制编译器发出类的确切名称,只需要实现者(编译器供应商)来决定什么是合适的。简而言之,名称取决于编译器。


这是两种不同的工具。 typeof返回表达式的类型,但它不是标准的。在C ++ 0x中,有一个名为decltype的东西可以完成同样的工作AFAIK。

decltype(0xdeedbeef) number = 0; // number is of type int!
decltype(someArray[0]) element = someArray[0];

typeid与多态类型一起使用。例如,假设cat派生animal

animal* a = new cat; // animal has to have at least one virtual function
...
if( typeid(*a) == typeid(cat) )
{
    // the object is of type cat! but the pointer is base pointer.
}

答案 4 :(得分:4)

当被要求时,

typeid在运行时提供数据的类型。 Typedef是一个编译时构造,它定义了之后所述的新类型。 C ++中没有typeof 输出显示为(显示为内容注释):

std::cout << typeid(t).name() << std::endl;  // i
std::cout << typeid(person).name() << std::endl;   // 6Person
std::cout << typeid(employee).name() << std::endl; // 8Employee
std::cout << typeid(ptr).name() << std::endl;      // P6Person
std::cout << typeid(*ptr).name() << std::endl;     //8Employee

答案 5 :(得分:3)

你可以使用Boost demangle来完成一个漂亮的名字:

#include <boost/units/detail/utility.hpp>

等等

To_main_msg_evt ev("Failed to initialize cards in " + boost::units::detail::demangle(typeid(*_IO_card.get()).name()) + ".\n", true, this);