c++ RTTI(runtime type info)

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

RTTI提供了以下两个非常有用的操作符:

(1)typeid操作符,返回指针和引用所指的实际类型。

(2)dynamic_cast操作符,将基类类型的指针或引用安全地转换为派生类型的指针或引用。

面向对象的编程语言,象C++,Java,delphi都提供了对RTTI的支持。 本文将简略介绍 RTTI
的一些背景知识、描述 RTTI 的概念,并通过具体例子和代码介绍什么时候使用以及如何使用 RTTI;本文还将详细描述两个重要的 RTTI
运算符的使用方法,它们是 typeid 和dynamic_cast。

其实,RTTI
在C++中并不是什么新的东西,它早在十多年以前就已经出现了。但是大多数开发人员,包括许多高层次的C++程序员对它并不怎么熟悉,更不用说使用 RTTI
来设计和编写应用程序了。

一些面向对象专家在传播自己的设计理念时,大多都主张在设计和开发中明智地使用虚拟成员函数,而不用
RTTI 机制。但是,在很多情况下,虚拟函数无法克服本身的局限。每每涉及到处理异类容器和根基类层次(如
MFC)时,不可避免要对对象类型进行动态判断,也就是动态类型的侦测。如何确定对象的动态类型呢?答案是使用内建的 RTTI 中的运算符:typeid 和
dynamic_cast。

在C++中存在虚函数,也就存在了多态性,对于多态性的对象,在程序编译时可能会出现无法确定对象的类型的情况。当类中含有虚函数时,其基类的指针就可以指向任何派生类的对象,这时就有可能不知道基类指针到底指向的是哪个对象的情况,类型的确定要在运行时利用运行时类型标识做出。为了获得一个对象的类型可以使用typeid函数,该函数反回一个对type_info类对象的引用,要使用typeid必须使用头文件<typeinfo>,因为typeid是一个返回类型为typ_info的引用的函数所以这里有必要先介绍一下type_info类.

typeid函数

该函数的主要作用就是让用户知道当前的变量是什么类型的,比如使用typeid(a).name()就能知道变量a是什么类型的。因为typeid()函数是一个返回类型为const
typeid_info&类型的函数,所以下面先对type_info类作下介绍

type_info类

该类的具体实现方式依编译器而定,但一般都有如下的成员定义

classtype_info

{

private:

type_info(consttype_info&);

type_info&operator=(consttype_info&);//type_info类的复制构造函数和赋值运算符是私有的。

public:

virtual~type_info();//析构函数

booloperator==(consttype_info&)const;//在type_info类中重载了==运算符,该运算符可以比较两个对象的类型是否相等。

booloperator!=(consttype_info&)const;//重载的!=运算符,以比较两个对象的类型是否不相等

constchar*name()const;//使用得较多的成员函数name,该函数反回对象的类型的名字。前面使用的typeid(a).name()就调用了该成员函数

boolbefore(consttype_info&);

};

因为type_info类的复制构造函数和赋值运算符都是私有的,所以不允许用户自已创建type_info的对象,比如type_info
A;错误,没有默认的构造函数。唯一要使用type_info类的方法就是使用typeid函数。

typeid函数怎样创建type_info类的对象

该函数返回type_info类对象的引用,即形式为const type_info&
typeid();因此也可以说typeid函数是type_info类的一个引用对象,可以访问type_info类的成员。但因为不能创建type_info类的对象,而typeid又必须返回一个类型为type_info类型的对象的引用,所以怎样在typeid函数中创建一个type_info类的对象以便让函数返回type_info类对象的引用就成了问题。这可能是把typid函数声明为了type_info类的友元函数来实现的,默认构造函数是私有的并不能阻止该类的友元函数创建该类的对象。所以typeid函数如果是友元的话就可以访问type_info类的私有成员,从而可以创建type_info类的对象,从而可以创建反回类型为type_info类的引用。

举个例子:

class A{private:A(){} A(const A&){} A& operator
=(const A&){} friend A&
f();};这里把类A的默认构造函数,复制构造函数和赋值操作符定为私有从而防止创建类A的对象,但函数f()是类A的友元,所以在函数f()中可以创建类A的对象。同时为了实现函数f()返回的对象类型是A的引用,就必须在函数f中创建一个类A的对象以作为函数f的返回值,比如函数f可以这样定义A&
f(){A ma; cout<<”f”<<endl; return ma}。

(个人解:A ma是局部对象,函数运行完后会释放掉,不能返回ma,这里好像有错误。)

因为typeid函数是type_info类的对象,也就是说可以用该函数访问type_info类的成员,即type_info类中重载的=
=和!=运算符,name()和before()成员函数,比如typid(a).name()和typid(a) == typid(b)等等。


// expre_typeid_Operator.cpp
// compile with: /GR /EHsc
#include <iostream>
#include <typeinfo.h>

class Base
{
public:
virtual void vvfunc() {}
};

class Derived : public Base {};

using namespace std;

int main()
{
Derived* pd = new Derived;
Base* pb = pd;
int i = 0;

cout << typeid( i ).name() << endl; // prints "int"
cout << typeid( 3.14 ).name() << endl; // prints "double"
cout << typeid( pb ).name() << endl; // prints "class Base *"
cout << typeid( *pb ).name() << endl; // prints "class Derived"
cout << typeid( pd ).name() << endl; // prints "class Derived *"
cout << typeid( *pd ).name() << endl; // prints "class Derived"

delete pd;
}

typeid最常见的用途是比较两个表达式的类型,或者将表达式的类型与特定类型相比较。


Base *bp;
Derived *dp;
// compare type at run time of two objects
if (typeid(*bp) == typeid(*dp))
{
// bp and dp point to objects of the same type
}
// test whether run time type is a specific type
if (typeid(*bp) == typeid(Derived))
{
// bp actually points a Derived
}

注意:如果是typeid(bp),则是对指针进行测试,这会返回指针(bp)的静态编译时类型(Base *)。

如果指针p的值是0,,并且指针所指的类型是带虚函数的类型,则typeid(*p)抛出一个bad_typeid异常。

参考:http://baike.baidu.com/view/1042388.htm

更多:

http://blog.csdn.net/acdnjjjdjkdckjj/article/details/6326189

http://dxwang.blog.51cto.com/384651/79036

http://blog.csdn.net/yueguanghaidao/article/details/7935960

c++ RTTI(runtime type info),布布扣,bubuko.com

时间: 2024-10-13 22:48:00

c++ RTTI(runtime type info)的相关文章

C++ - RTTI(RunTime Type Information)执行时类型信息 具体解释

RTTI(RunTime Type Information)执行时类型信息 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24369987 RTTI, RunTime Type Information, 执行时类型信息, 是多态的主要组成部分, 通过执行时(runtime)确定使用的类型, 执行不同的函数,复用(reuse)接口. dynamic_cast<>能够 使基类指针转换为派生类的指针, 通过推断指针的类型

MFC中的RTTI(Runtime Type Identification, 运行时类型识别)详解(参考《深入浅出MFC》)

在MFC中的RTTI的实现,主要是利用一个名为CRuntimeClass的结构来链接各个"有关系的类"的信息来实现的.简单来说,就是在需要用到RTTI技术的类内建立CRuntimeClass的静态变量,来储存该类的相关信息(包括类名.基类的CRuntimeClass结构的指针.让"有关系的类"的信息形成链表的next指针.以及链表的首指针(静态)等信息),这里的"有关系"指的是从同一个基类继承下来的所有的类之间的关系.这些信息(CRuntimeC

RTTI (Run-Time Type Identification,通过运行时类型识别) 转

参考一: RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型. RTTI提供了以下两个非常有用的操作符: (1)typeid操作符,返回指针和引用所指的实际类型: (2)dynamic_cast操作符,将基类类型的指针或引用安全地转换为派生类型的指针或引用. 面向对象的编程语言,象C++,Java,delphi都提供了对RTTI的支持. 本文将简略介绍 RTTI 的一些背景知识.描述 R

ABAP运行时类型服务 Runtime Type Services (RTTS)

RTTS (RunTime Type Services)允许获得变量的定义,或者在程序运行期间创建它们.RTTS由2个组件组成: RTTI(RunTime Type Identification)用于获取已存在类型或已存在变量的定义. RTTC(RunTime Type Creation)用于使用定义创建新的变量:需要创建的变量必须通过ABAP语句CREATE DATA ... TYPE HANDLE创建. RTTI和RTTC可以通过使用类CL_ABAP_*DESCR中的方法访问.每个类都有RT

moon RTTI --running-time type identification运行时类型确定

JVM 三种预定义类型类加载器 1)启动类(Bootstrap)加载器  :<Java_Runtime_Home>/lib下面的核心类库或-Xbootclasspath选项指定的jar包加载到内存中 Bootstrap /?bu:tstræp/引导程序; 解靴带; 靴袢; 自益; 2)拓展(Extension)类加载器:由Sun的ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现的.它负责将< Java_Runtime_Home >

swift runtime type

var v = 1.0; println(v.dynamicType);//Swift.Double

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

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

C++ 宏、范型和RTTI 浅析

[摘要] RTTI(Run-Time Type Identification)是面向对象程序设计中一种重要的技术.现行的C++标准对RTTI已经有了明确的支持.不过在某些情况下出于特殊的开发需要,我们需要自己编码来实现.本文介绍了一些关于RTTI的基础知识及其原理和实现,并分析比较三者是线上的差异与联系. [正文] RTTI 的需求 和很多其他语言一样,C++是一种静态类型语言.其数据类型是在编译期就确定的,不能在运行时更改.然而由于面向对象程序设计中多态性的要求,C++中的指针或引用(Refe

Delphi 的RTTI机制浅探&lt;一&gt;

目 录===============================================================================⊙ DFM 文件与持续机制(persistent)⊙ ReadComponentResFile / WriteComponentResFile 函数⊙ Delphi 持续机制框架简述⊙ 一个 TForm 对象的创建过程⊙ TStream Class 和 TStream.ReadComponent 方法⊙ TReader Class 和