C++ typeid type_info (转)

typeid是C++的一个关键字,其作用是在程序运行时,返回对象的类型,即所谓的RTTI(Run Time Type Identification), 它使程序能够获取由指针或引用所指向的对象的实际类型,即允许“用指向基类的指针或引用来操作对象”的程序能够获取到“这些指针或引用所指对象”的实际派生类型。在C++中,为了支持RTTI提供了两个操作符:dynamic_cast和typeid。
typeid操作符的返回结果是名为type_info的标准库类型的对象的引用。 type_info在typeinfo头文件中定义:

class type_info {
public:
virtual ~type_info();
bool operator== (const type_info& rhs) const;
bool operator!= (const type_info& rhs) const;
bool before (const type_info& rhs) const;
const char* name() const;
private:
type_info (const type_info& rhs);
type_info& operator= (const type_info& rhs);
};

如下内容摘自http://www.cplusplus.com/reference/typeinfo/type_info/:

typeid can be applied to any typed expression, including a type itself, to retrieve the its type_info.

When typeid is applied to a reference or dereferenced pointer to an object of a polymorphic class type (a class declaring or inheriting a virtual function), it considers its dynamic type (i.e., the type of the most derived object). This requires the RTTI (Run-time type information) to be available.

When typeid is applied to a dereferenced null pointer a bad_typeid exception is thrown.

type_info成员介绍如下:

operator==
operator!=
Comparison operators. They return whether the two types describe the same type.
A derived type is not considered the same type as any of its base classes.

before
Returns true if the type precedes the type of rhs in the collation order.
The collation order is just an internal order kept by a particular implementation and is not necessarily related to inheritance relations or declaring order.
name
Returns a null-terminated character sequence with a human-readable name for the type.
copy constructor and copy operator
These are private, preventing type_info values from being copiable.


Example:

// type_info example
#include <iostream>
#include <typeinfo>
using namespace std;

struct Base {};
struct Derived : Base {};
struct Poly_Base {virtual void Member(){}};
struct Poly_Derived: Poly_Base {};

int main() {
// built-in types:
int i;
int * pi;
cout << "int is: " << typeid(int).name() << endl;
cout << " i is: " << typeid(i).name() << endl;
cout << " pi is: " << typeid(pi).name() << endl;
cout << "*pi is: " << typeid(*pi).name() << endl << endl;

// non-polymorphic types:
Derived derived;
Base* pbase = &derived;
cout << "derived is: " << typeid(derived).name() << endl;
cout << " *pbase is: " << typeid(*pbase).name() << endl;
cout << boolalpha << "same type? "; 
cout << ( typeid(derived)==typeid(*pbase) ) << endl << endl;

// polymorphic types:
Poly_Derived polyderived;
Poly_Base* ppolybase = &polyderived;
cout << "polyderived is: " << typeid(polyderived).name() << endl;
cout << " *ppolybase is: " << typeid(*ppolybase).name() << endl;
cout << boolalpha << "same type? "; 
cout << ( typeid(polyderived)==typeid(*ppolybase) ) << endl << endl;

Output:
int is: i
i is: i
pi is: Pi
*pi is: i

derived is: 7Derived
*pbase is: 4Base
same type? false

polyderived is: 12Poly_Derived
*ppolybase is: 12Poly_Derived
same type? true