C++ 标准库之typeid
2014-05-04 22:22
253 查看
本文只讲述typeid这个操作符,呃 ,它确实是一个操作符,类似于 sizeof 操作符。
在将该操作符之前,不得不提的是RTTI(Run-Time
Type Identification,运行时类型识别),其实就是说
在运行期得到对象的实际的类型。这立刻使我们想到了“可以通过基类的指针和引用可以指向实际的派生类型”。
啊哦,答对了,这就是typeid这个强大操作符所做的事。
既然提到了typeid,那么该操作符的返回类型便不得不提,该操作符的返回类型是type_info的标准库类型的引
用 , 这是定义在标准库的一个类类型class
type_info; 值得一提的是,该类的拷贝构造函数以及赋值操作符被定义
为private,这是禁止复制该类型的对象。
创建type_info对象的唯一方法,便是调用typeid操作符。
该类中最常用的成员函数name函数,该函数的返回类型是一个C风格的字符串,用于表示类型的id。
该函数同样是一个异常安全的函数,即不抛出异常。
当然了,对于在编译器与运行期类型一直的对象,typeid同样适用,比如内置类型:
例如下面的代码:
上述代码用于获取 int 以及 double 的类型id:
注:在不同的编译器设置下,输出的结果可能不同。
在我的编译器下,输出的结果是:
那么,接下来进入typeid的真正意图,首先查看下面的代码:
相比看到这儿,读者应该会觉得生成的结果是什么了吧?那么不要对接下来的结果感到意外啦!!
上述代码的执行结果:
结果跟想象的怎么不一样!不对,是完全不一样,typeid是不是就是实现错了呢!!!
稍安勿躁,接下来,本文最重要的一句话:
当typeid操作符的操作数是不带有虚函数的类类型时,typeid操作符会指出操作数的类型,而不是底层对象的类型。
那么,这句话就很好的解释了上面的结果,至于typeid,那么我们可以很容易的改变上述代码,检验其正确性:
添加了一个虚函数即可,得到的结果就如预期一般了:
这里,提醒一点:当你需要一个虚函数,但是该类中没有对应的函数需要派生类重定义的时候,那么 虚析构函
数 你绝对不能忘记,这是一个很好的选择!!!
关于typeid,上述基本已经介绍完毕,一个很强大的操作符。这里不禁会想到另一个操作符 dynamic_cast,其
实这不过是++的
RTTI 的两种策略罢了。
在将该操作符之前,不得不提的是RTTI(Run-Time
Type Identification,运行时类型识别),其实就是说
在运行期得到对象的实际的类型。这立刻使我们想到了“可以通过基类的指针和引用可以指向实际的派生类型”。
啊哦,答对了,这就是typeid这个强大操作符所做的事。
既然提到了typeid,那么该操作符的返回类型便不得不提,该操作符的返回类型是type_info的标准库类型的引
用 , 这是定义在标准库的一个类类型class
type_info; 值得一提的是,该类的拷贝构造函数以及赋值操作符被定义
为private,这是禁止复制该类型的对象。
创建type_info对象的唯一方法,便是调用typeid操作符。
该类中最常用的成员函数name函数,该函数的返回类型是一个C风格的字符串,用于表示类型的id。
该函数同样是一个异常安全的函数,即不抛出异常。
当然了,对于在编译器与运行期类型一直的对象,typeid同样适用,比如内置类型:
例如下面的代码:
#include #include // typeid using namespace std; int main() { int iVal; cout << typeid(iVal).name() << endl; double dVal; cout << typeid(dVal).name() << endl; return 0; }
上述代码用于获取 int 以及 double 的类型id:
注:在不同的编译器设置下,输出的结果可能不同。
在我的编译器下,输出的结果是:
那么,接下来进入typeid的真正意图,首先查看下面的代码:
#include #include using namespace std; //类的定义不是我们的重点,因此假设为空 class Base {}; class Derived : public Base {}; int main() { //Base对象 Base b; cout << "b type : " << typeid(b).name() << endl; //Derived对象 Derived d; cout << "d type : " << typeid(d).name() << endl; //Base 指针 Base *pb = new Base(); cout << "pb type : " << typeid(pb).name() << endl; //Base 指针指向Derived对象 Base *pd = new Derived() ; cout << "pd type : " << typeid(pd).name() << endl; cout << "*pd type : " <
相比看到这儿,读者应该会觉得生成的结果是什么了吧?那么不要对接下来的结果感到意外啦!!
上述代码的执行结果:
结果跟想象的怎么不一样!不对,是完全不一样,typeid是不是就是实现错了呢!!!
稍安勿躁,接下来,本文最重要的一句话:
当typeid操作符的操作数是不带有虚函数的类类型时,typeid操作符会指出操作数的类型,而不是底层对象的类型。
那么,这句话就很好的解释了上面的结果,至于typeid,那么我们可以很容易的改变上述代码,检验其正确性:
#include #include using namespace std; class Base { public: virtual ~Base(){} }; class Derived : public Base {}; int main() { Base b; cout << "b type : " << typeid(b).name() << endl; Derived d; cout << "d type : " << typeid(d).name() << endl; Base *pb = new Base(); cout << "pb type : " << typeid(pb).name() << endl; Base *pd = new Derived() ; cout << "pd type : " << typeid(pd).name() << endl; cout << "*pd type : " <
添加了一个虚函数即可,得到的结果就如预期一般了:
这里,提醒一点:当你需要一个虚函数,但是该类中没有对应的函数需要派生类重定义的时候,那么 虚析构函
数 你绝对不能忘记,这是一个很好的选择!!!
关于typeid,上述基本已经介绍完毕,一个很强大的操作符。这里不禁会想到另一个操作符 dynamic_cast,其
实这不过是++的
RTTI 的两种策略罢了。
相关文章推荐
- C++ 有名库的介绍, 准标准库Boost
- C /C++标准库 - <ctime> (time.h)
- c++ 标准库map和set
- C++ 第三章标准库类型
- C++ 标准库定义了更高级的抽象数据类型
- C++<typeinfo>之typeid
- [C/C++标准库]_[中级]_[使用stringstream作为内存流读取]
- 从零开始学C++之RTTI、dynamic_cast、typeid、类与类之间的关系uml
- c++ 标准库MAP用法
- C++ typeid 与RTTI(Runtime Type Information)
- Windows Mobile下native c++ typeid的使用
- 使用typeid和RTTI C++获取对象运行时类名称
- [C/C++标准库]_[初级]_[优先队列priority_queue的使用]
- 列出比较容易忘记的 C++(C)语言语法及标准库
- C++ typeid
- C++ 中标准库 map 和 hash_map 的使用方法
- C++的iostream标准库介绍
- C++ typeid() 基类必须是多态类
- C++及其标准库概览---第二,三章
- C++ typeid运算符