一、typeid的概念
C++里的typeid
是运算符,可以获取一个表达式的类型信息。它的返回值是一个类型信息的引用类型,表示该表达式的数据类型。
// 示例代码
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
int a = 0;
double b = 1.0;
const string c = "hello";
cout << typeid(a).name() << endl;
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;
return 0;
}
运行以上代码,输出如下:
i d NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
可以看到输出的内容都是类型信息,分别对应int
类型、double
类型和string
类型。
二、typeid的使用
C++里的typeid
可以用于不同的场景,本节将会介绍一些常见的使用方式。
1. typeid与指针
使用typeid
获取指针所指向的类型信息。
// 示例代码
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
int a = 0;
double b = 1.0;
const string c = "hello";
cout << typeid(&a).name() << endl;
cout << typeid(&b).name() << endl;
cout << typeid(&c).name() << endl;
return 0;
}
运行以上代码,输出如下:
Pi Pd PKc
可以看到输出的内容都是指针类型信息。
2. typeid与多态及继承
运用typeid
可以方便地获取对象的类型信息,在多态及继承的场景下特别有用。
示例代码如下:
// 示例代码
#include <iostream>
#include <typeinfo>
using namespace std;
class Animal {
public:
virtual void speak() {}
};
class Cat : public Animal {
public:
virtual void speak() {
cout << "I'm a cat." << endl;
}
};
class Dog : public Animal {
public:
virtual void speak() {
cout << "I'm a dog." << endl;
}
};
void outputType(Animal* a) {
if (typeid(*a) == typeid(Cat)) {
cout << "Cat" << endl;
} else if (typeid(*a) == typeid(Dog)) {
cout << "Dog" << endl;
}
}
int main()
{
Cat c;
Dog d;
Animal* a1 = &c;
Animal* a2 = &d;
outputType(a1);
outputType(a2);
return 0;
}
运行以上代码,输出如下:
Cat Dog
可以看到在outputType()
中使用了typeid
来判断传入的指针的类型,并输出类型名称。
三、typeid的局限性
虽然使用typeid
可以方便地获取对象的类型信息,但是在某些场景下会受到其局限性的影响。
1. typeid与基本类型
在基本类型(例如int
、double
等)的场景下,typeid
无法提供具体的类型信息。
// 示例代码
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
int i = 0;
double d = 1.0;
cout << typeid(i).name() << endl;
cout << typeid(d).name() << endl;
return 0;
}
运行以上代码,输出如下:
i d
可以看到输出的内容只包含类型信息,无法提供有用信息。
2. typeid与泛型
在虚拟函数和泛型编程中,使用typeid
也会受到一定的限制。
// 示例代码
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
void printType(T t) {
cout << typeid(t).name() << endl;
}
int main()
{
int i = 0;
double d = 1.0;
const string c = "hello";
printType(i);
printType(d);
printType(c);
return 0;
}
运行以上代码,输出如下:
i d NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
可以看到在使用模板函数时,typeid
的显示方式与普通的方法有所不同,无法直接获取类型名称。
四、总结
C++中的typeid
可以方便地获取类型信息,与面向对象编程的多态机制和继承机制相辅相成,在某些场景下使用效果明显。但值得注意的是,typeid
也存在一些局限性,比如在基本类型和泛型编程的场景下效果不佳,需要开发者在使用时进行注意。