C++ 提供了 typeid 运算符用来获取一个表达式的类型信息。
- 对于基本类型(int、double等)的对象,类型信息所包含的内容比较简单,主要是指数据的类型;
- 对于类类型的对象,类型信息是指对象所属的类、所包含的成员、所在的继承关系等。
typeid 会把获取到的类型信息保存到一个 type_info 类型的对象里面,并返回该对象的常引用;当需要具体的类型信息时,可以通过成员函数来提取。
但是,ISO C++标准并没有确切定义type_info,它的确切定义编译器相关的,标准只规定了其实现必需提供如下四种操作:
- t.name():返回类型的C-style字符串,用来表示相应的类型名;
- t1 == t2:如果两个对象t1和t2类型相同,则返回true;否则返回false;
- t1 != t2:如果两个对象t1和t2类型不同,则返回true;否则返回false;
- t1.before(t2):返回指出t1是否出现在t2之前的bool值。
需要注意的是:type_info 在各个平台的实现不一致,比如 name(),在 VC/VS 下的输出结果分别是 int 和 class Base,而在 GCC 下的输出结果分别是 i 和 4Base。
#include <iostream>
using namespace std;
int main()
{
cout << "bool : " << typeid(bool).name() << endl;
cout << "char : " << typeid(char).name() << endl;
cout << "short : " << typeid(short).name() << endl;
cout << "int : " << typeid(int).name() << endl;
cout << "long : " << typeid(long).name() << endl;
cout << "float : " << typeid(float).name() << endl;
cout << "double : " << typeid(double).name() << endl;
return 0;
}
上面这段代码在GCC下,运行结果为:
下面是类类型的对象。
#include <iostream>
using namespace std;
class Base {};
class Derived : public Base {};
int main()
{
Base b; // Base对象
cout << "typeid(b) : " << typeid(b).name() << endl;
Derived d; // Derived对象
cout << "typeid(d) : " << typeid(d).name() << endl;
Base* pb; // Base指针
cout << "typeid(pb) : " << typeid(pb).name() << endl;
Derived* pd; // Derived指针
cout << "typeid(pd) : " << typeid(pd).name() << endl;
Base* pbd = new Derived(); // Base指针指向Derived
cout << "typeid(pbd): " << typeid(pbd).name() << endl;
delete pbd;
pbd = nullptr;
return 0;
}
运行结果为:
这里需要注意,当通过基类的指针指向派生类型时,该指针仍是基类型别的指针类型。
在实际应用中,typeid 主要用于返回指针或引用所指对象的实际类型,且大部分情况下,typeid 运算符用于判断两个类型是否相等。
if (typeid(b) != typeid(d)) {
cout << "b != d" << endl;
}
if (typeid(pb) == typeid(pbd)) {
cout << "pb == pbd" << endl;
}