typeid 运算符
- 查询类型的信息。
- 用于必须知晓多态对象的动态类型的场合以及静态类型鉴别。
- 语法
(1) typeid( 类型 )
(2) typeid( 表达式 ) - typeid 表达式为左值表达式,指代一个具有静态存储期的,多态类型 或某个其派生类型的const std::type_info 对象。
- 类 type_info 指定一个类型的信息,包括类型的名称和比较二个类型相等的方法。这是 typeid 运算符所返回的类。
- 获取完整类型名方法:typeid(类型名/表达式).name()
#include <iostream>
#include <string>
#include <typeinfo>
struct Base {}; // 非多态
struct Derived : Base {};
struct Base2 { virtual void foo() {} }; // 多态
struct Derived2 : Base2 {};
int main() {
int myint = 50;
std::string mystr = "string";
double *mydoubleptr = nullptr;
std::cout << "myint has type: " << typeid(myint).name() << '\n'
<< "mystr has type: " << typeid(mystr).name() << '\n'
<< "mydoubleptr has type: " << typeid(mydoubleptr).name() << '\n';
// std::cout << myint 为多态类型的泛左值表达式;求值
const std::type_info& r1 = typeid(std::cout << myint);
std::cout << '\n' << "std::cout<<myint has type : " << r1.name() << '\n';
// std::printf() 不是多态类型的泛左值表达式;不求值
const std::type_info& r2 = typeid(std::printf("%d\n", myint));
std::cout << "printf(\"%d\\n\",myint) has type : " << r2.name() << '\n';
// 非多态左值时为静态类型
Derived d1;
Base& b1 = d1;
std::cout << "reference to non-polymorphic base: " << typeid(b1).name() << '\n';
Derived2 d2;
Base2& b2 = d2;
std::cout << "reference to polymorphic base: " << typeid(b2).name() << '\n';
try {
// 解引用空指针:对于非多态表达式 OK
std::cout << "mydoubleptr points to " << typeid(*mydoubleptr).name() << '\n';
// 解引用空指针:对多态左值则不行
Derived2* bad_ptr = nullptr;
std::cout << "bad_ptr points to... ";
std::cout << typeid(*bad_ptr).name() << '\n';
} catch (const std::bad_typeid& e) {
std::cout << " caught " << e.what() << '\n';
}
}
可能的输出:
myint has type: int
mystr has type: std::basic_string<char, std::char_traits<char>, std::allocator<char> >
mydoubleptr has type: double*
50
std::cout<<myint has type : std::basic_ostream<char, std::char_traits<char> >
printf("%d\n",myint) has type : int
reference to non-polymorphic base: Base
reference to polymorphic base: Derived2
mydoubleptr points to double
bad_ptr points to... caught std::bad_typeid