typeid( dataType )
typeid( expression )
( ),而 typeid 必须带上括号。
#include <iostream>
#include <typeinfo>
using namespace std;
class Base{ };
struct STU{ };
int main(){
//获取一个普通变量的类型信息
int n = 100;
const type_info &nInfo = typeid(n);
cout<<nInfo.name()<<" | "<<nInfo.raw_name()<<" | "<<nInfo.hash_code()<<endl;
//获取一个字面量的类型信息
const type_info &dInfo = typeid(25.65);
cout<<dInfo.name()<<" | "<<dInfo.raw_name()<<" | "<<dInfo.hash_code()<<endl;
//获取一个对象的类型信息
Base obj;
const type_info &objInfo = typeid(obj);
cout<<objInfo.name()<<" | "<<objInfo.raw_name()<<" | "<<objInfo.hash_code()<<endl;
//获取一个类的类型信息
const type_info &baseInfo = typeid(Base);
cout<<baseInfo.name()<<" | "<<baseInfo.raw_name()<<" | "<<baseInfo.hash_code()<<endl;
//获取一个结构体的类型信息
const type_info &stuInfo = typeid(struct STU);
cout<<stuInfo.name()<<" | "<<stuInfo.raw_name()<<" | "<<stuInfo.hash_code()<<endl;
//获取一个普通类型的类型信息
const type_info &charInfo = typeid(char);
cout<<charInfo.name()<<" | "<<charInfo.raw_name()<<" | "<<charInfo.hash_code()<<endl;
//获取一个表达式的类型信息
const type_info &expInfo = typeid(20 * 45 / 4.5);
cout<<expInfo.name()<<" | "<<expInfo.raw_name()<<" | "<<expInfo.hash_code()<<endl;
return 0;
}
运行结果:nInfo.name()、objInfo.name()在 VC/VS 下的输出结果分别是int和class Base,而在 GCC 下的输出结果分别是i和4Base。objInfo.name()语句,VC/VS 下返回“class Base”,但 GCC 下返回“4Base”。
关于运算符重载,我们将在《C++运算符重载》一章中详细讲解。raw_name() 是 VC/VS 独有的一个成员函数,hash_code() 在 VC/VS 和较新的 GCC 下有效。
char *str; int a = 2; int b = 10; float f;类型判断结果为:
| 类型比较 | 结果 | 类型比较 | 结果 |
|---|---|---|---|
| typeid(int) == typeid(int) | true | typeid(int) == typeid(char) | false |
| typeid(char*) == typeid(char) | false | typeid(str) == typeid(char*) | true |
| typeid(a) == typeid(int) | true | typeid(b) == typeid(int) | true |
| typeid(a) == typeid(a) | true | typeid(a) == typeid(b) | true |
| typeid(a) == typeid(f) | false | typeid(a/b) == typeid(int) | true |
typeid(a) == typeid(b)的结果为 true,可以说明,一个类型不管使用了多少次,编译器都只为它创建一个对象,所有 typeid 都返回这个对象的引用。
class Base{};
class Derived: public Base{};
Base obj1;
Base *p1;
Derived obj2;
Derived *p2 = new Derived;
p1 = p2;
类型判断结果为:| 类型比较 | 结果 | 类型比较 | 结果 |
|---|---|---|---|
| typeid(obj1) == typeid(p1) | false | typeid(obj1) == typeid(*p1) | true |
| typeid(&obj1) == typeid(p1) | true | typeid(obj1) == typeid(obj2) | false |
| typeid(obj1) == typeid(Base) | true | typeid(*p1) == typeid(Base) | true |
| typeid(p1) == typeid(Base*) | true | typeid(p1) == typeid(Derived*) | false |
typeid(*p1) == typeid(Base)和typeid(p1) == typeid(Base*)的结果为 true 可以说明:即使将派生类指针 p2 赋值给基类指针 p1,p1 的类型仍然为 Base*。
typeinfo头文件,声明形式类似于:
class type_info {
public:
virtual ~type_info();
int operator==(const type_info& rhs) const;
int operator!=(const type_info& rhs) const;
int before(const type_info& rhs) const;
const char* name() const;
const char* raw_name() const;
private:
void *_m_data;
char _m_d_name[1];
type_info(const type_info& rhs);
type_info& operator=(const type_info& rhs);
};
它的构造函数是 private 属性的,所以不能在代码中直接实例化,只能由编译器在内部实例化(借助友元)。而且还重载了“=”运算符,也是 private 属性的,所以也不能赋值。
版权说明:Copyright © 广州松河信息科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州松河信息科技有限公司 版权所有