c++ RTTI

RTTI(Run-Time Type Information,通过运行时类型信息)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。

c++有三个支持RTTI的元素

1)如果可能的话,dynamic_cast运算符将使用一个指向基类的指针来生成一个指向派生类的指针,否则,该运算符返回0 ——空指针。

dynamic_cast < Type *> (pt);

通常,如果指向对象(*pt)的类型为Type或者是从Type直接或间接派生而来的类型,则上述表达式将指针pt转换为Type类型的指针。

否则,结果为0,即空指针。

2) typeid 运算符返回i一个指出对象的类型的值。

typeid对象使得能够确定两个对象是否是同种类型,它与sizeof有些相像,可以接受两种参数:

类名

结果为对象的表达式

它返回一个对type_info对象的引用。

3)type_info结构存储了有关特定类型的信息。

type_info是一个在头文件typeinfo中定义的一个类,重载了== 和 !=运算符

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <typeinfo>
using std::cout;
class Grand
{
    private:
      int hold;
    public:
      Grand(int h = 0) : hold(h) {}
      virtual void Speak() const { cout << "I am a grand class!\n";}
      int Value() const { return hold; }
};

class Superb : public Grand
{
    public:
      Superb(int h = 0) : Grand(h) {}
      void Speak() const { cout << "I am a superb class!!\n"; }
      virtual void Say() const
      {
          cout << "I hold the superb value of " << Value() << "!\n";
      }
};

class Magnificent : public Superb
{
    private:
      char ch;
    public:
      Magnificent( int h = 0, char c = ‘A‘) : Superb(h), ch(c) {}
      void Speak() const { cout << "I am a magnificent class!!!\n"; }
      void Say() const { cout << "I hold  the character "<< ch <<
                 " and the integer " << Value() << "!\n"; }
};

Grand* GetOne();

int main()
{
    std::srand(std::time(0));
    Grand* pg;
    Superb* ps;
    for (int i = 0; i < 5; i++)
    {
        pg = GetOne();
        pg->Speak();
        if (ps = dynamic_cast<Superb *>(pg))
            ps->Say();
        if (typeid(Magnificent) == typeid(*pg))
            cout<<"Yes, you‘re really magnificent.\n";
    }
    return 0;
}

//随机创建三种类中某种类的对象,并对其进行初始化,然后将
//地址作为Grand* 指针返回。
Grand* GetOne()
{
    Grand* p;
    switch (std::rand() % 3)
    {
        case 0: p = new Grand(std::rand() % 100);
            break;
        case 1: p = new Superb(std::rand() % 100);
            break;
        case 2: p = new Magnificent(std::rand() % 100,‘A‘+std::rand() % 26);            break;
    }
    return p;
}

运行结果:

C++的RTTI提供了几个最基本的功能:

1、安全的downcast,当你使用dynamic_cast动态从基类指针转换成子类指针的时候,RTTI能保证安全的转换,如果类型不符则抛出一个bad_cast异常。

2、动态获取一个对象的类名称。你可以使用typeid获得一个type_info对象,这个对象保存了这个类型的最基本信息,比如名称。

3、在继承树上遍历,使用typeid获得的type_info对象提供一个before方法,可以用于查找这个类型的基类。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-29 07:27:22

c++ RTTI的相关文章

c++中RTTI

RTTI 是"Runtime Type Information"的缩写,意思是:运行时类型信息.它提供了运行时确定对象类型的方法.本文将简略介绍 RTTI 的一些背景知识.描述 RTTI 的概念,并通过具体例子和代码介绍什么时候使用以及如何使用 RTTI:本文还将详细描述两个重要的 RTTI 运算符的使用方法,它们是 typeid 和 dynamic_cast.如何确定对象的动态类型呢?答案是使用内建的 RTTI 中的运算符:typeid 和 dynamic_cast. typeid的

【Java基础】RTTI与反射之Java

一.引言 很多时候我们的程序可能需要在运行时识别对象和类的信息,比如多态就是基于运行时环境进行动态判断实际引用的对象.在运行时识别对象和类的信息主要有两种方式:1.RTTI,具体是Class对象,它假定我们在编译时已经知道了所有类型.2.反射机制,运行我们在运行时发现和使用类的信息. 二.RTTI RTTI(Run-Time Type Infomation),运行时类型信息.可以在运行时识别一个对象的类型.类型信息在运行时通过Class对象表示,Class对象包含与类有关的信息,可以使用Clas

QObject提供了QMetaObject元类信息(相当于RTTI和反射),信号与连接,父子关系,调试信息,属性,事件,继承关系,窗口类型,线程属性,时间器,对象名称,国际化

元类信息(相当于RTTI和反射),信号与连接,父子关系,调试信息,属性,事件,继承关系,窗口类型,线程属性,时间器,对象名称,国际化其中元类又提供了:classInfo,className,构造函数,多重祖先元类,method, property, Enumerator, Signal, Slot等等 http://doc.qt.io/qt-5/qobject.html http://doc.qt.io/qt-5/qmetaobject.html 我感觉Qt的出现,除了提供GUI以外,主要就是提

C++的 RTTI 观念和用途(非常详细)

自从1993年Bjarne Stroustrup [注1 ]提出有关C++ 的RTTI功能之建议﹐以及C++的异常处理(exception handling)需要RTTI:最近新推出的C++ 或多或少已提供RTTI. 然而,若不小心使用RTTI,可能会导致软件弹性的降低.本文将介绍RTTI的观念和近况﹐并说明如何善用它. 什么是RTTI﹖      在C++ 环境中﹐头文件(header file) 含有类之定义(class definition)亦即包含有关类的结构资料(representat

C 语言Struct 实现运行类型识别 RTTI

通过RTTI,能够通过基类的指针或引用来检索其所指对象的实际类型.c++通过下面两个操作符提供RTTI. (1)typeid:返回指针或引用所指对象的实际类型. (2)dynamic_cast:将基类类型的指针或引用安全的转换为派生类型的指针或引用. 对于带虚函数的类,在运行时执行RTTI操作符,返回动态类型信息:对于其他类型,在编译时执行RTTI,返回静态类型信息. 当具有基类的指针或引用,但需要执行派生类操作时,需要动态的强制类型转换(dynamic_cast).这种机制的使用容易出错,最好

java的RTTI和反射机制

RTTI,即Run-Time Type Identification,运行时类型识别.它假定我们在编译时已经知道了所有的类型.那么在运行时就能够自动识别每个类型. 很多时候需要进行向上转型,比如Base类派生出Derived类,但是现有的方法只需要将Base对象作为参数,实际传入的则是其派生类的引用.那么RTTI就在此时起到了作用,比如通过RTTI能识别出Derive类是Base的派生类,这样就能够向上转型为Derived.类似的,在用接口作为参数时,向上转型更为常用,RTTI此时能够判断是否可

delpi中的RTTI初试

java中的反射机制使我们能够在运行期间获取运行期类的信息,那么在delphi中有没有这样的功能呢?答案是有,实现这种功能的机制在delphi中叫做RTTI,废话少说,先来一段demo: 1.先定义一个demo类,注意这个类必须要以TPersistent为基类,代码如下: Delphi代码   unit Unit2; interface { TDemo } uses  Classes ; type TDemo = class(TPersistent) private protected publ

RTTI: dynamic_cast typeid

dynamic_cast:将基类类型的指针向派生类指针安全转换.多用于下行转换.上行转换时,和static_cast是一样的.C++类型转换看这里.下面主要说多态下的RTTI: 使用条件: 基类应有虚函数. 编译器需启用Runtime Type Information/Identification(RTTI),运行时类型信息.VS下在项目属性页下启用,如下,选 是: (VS2013测试:默认的留空不选也能正常使用dynamic_cast) 结果: 对指针进行dynamic_cast,失败返回nu

Delphi XE的RTTI增强,动态Hook某些内部事件

Delphi2010之后的RTTI做了很大休整,现在用起来很爽了哦.甚至可以获取某些类的内部私有单元,然后为其赋值!讲这个RTTI增强的,可以参考网上的多个博客内容,我列举一下: Delphi2010RTTI的增强 Delphi的Anymouse方法探秘 万一的Rtti系列 我这里的主要目的是挂钩某些内部私有事件,然后增加上一些自己的处理过程,这里我以TMenuItem的私有内部事件FOnChange作为例程. 这个私有事件在菜单内部绑定,我们平常状态下,在外部无法更改!但是XE之后这个问题不在

Delphi2010的RTTI增强

Delphi编译的文件体积增大了很多.很大一部分原因是因为Delphi2010默认提供了全信息的RTTI. 每一个数据类型都有全部运行时信息.例如可以在运行时获得结构体的成员以及成员类型等. 这个功能带来的方便就是我们可以写很多通用的序列化方法.也可以做一些类似OR的东西. 相反这个功能带来的缺点就是文件体积将增大. 不过有一个解决方案.就是把运行时信息的编译开关关掉.但是编译期间连接的库在Lib目录下.这些DCU文件却都是带RTTI信息的.所以编译出来的内容也会是非常大的.就只有修改VCL源代