C++ RTTI

RTTI

  • 运行时类型识别,根据基类指针或引用检索指针或引用所指对象的实际类型函数

  • 要使用RTTI,要求基类中具备虚函数spa

两种方法支持RTTI:指针

  • typeid操做符code

  • dynamic_cast操做符对象

dynamic_cast

动态类型转换

当须要经过基类指针或引用调用不是基类组成部分的派生类成员,就须要将基类指针或引用转换为派生类的指针或引用;固然也能够经过虚函数的方式,可是某些状况下是不可能使用虚函数的,好比静态成员函数;见下:继承


/*
 * main.cc
 *
 *  Created on: 2014年1月15日
 *      Author: root
 */

#include <stdio.h>

class A{
public:
    static void print(){ printf("A\n"); }
    virtual ~A(){ ; }
    /* 基类必需要用虚函数才能使用RTTI */
};

class B:public A{
public:
    static void print(){ printf("B\n"); }
    virtual ~B(){ ; }
};

int main(int argc,char *argv[]){
    A *a=new B;

    a->print();

    /* 若是要调用B版本的print;此时不可能经过虚函数
     * 因此必须使用动态类型转换,即dynamic_cast操做符 */
    /* 此时b的做用域为if块与if匹配的else块中 */
    if(B *b=dynamic_cast<B*>(a))
        b->print();
    else
        a->print();

    delete a;
    return 0;
}


dynamic_cast语法

dynamic_cast<派生类指针或引用>(基类指针或引用),将基类指针或引用转换为同一继承层次中派生类的指针或引用;作用域

转换失败

dynamic_cast会进行运行时检查,若是基类指针或引用所指对象的实际类型不是'<派生类指针或引用>'类型,如:字符串


class A{ virtual ~A(){} };
class B:public A{};
class C:public A{};

int main(int argc,char *argv[]){
    A *a=new B;
    dynamic_cast<C*>(a);
    /* 此时就会转换失败 */
    delete a;
    return 0;
}

对于 dynamic_cast<派生类指针>(基类指针):io


  • 转换失败的话,返回0;ast

对于 dynamic_cast<派生类引用>(基类引用):

  • 因为不存在空引用,因此转换失败的话,抛出bad_cast异常;

typeid

typeid(表达式),返回type_info类型,type_info类是对表达式的类型的一个包装,若是有虚函数支持的话,则会返回表达式的运行时实际类型;type_info支持如下操做:


/* 必须包含 <typeinfo> 头文件才能使用 */
bool operator==(const type_info &__type);
bool operator!=(const type_info &__type);
/* 判断两个类型是否相等 */

const char *name()const;
/* 返回类型的字符串表示 */


/*
 * main.cc
 *
 *  Created on: 2014年1月15日
 *      Author: root
 */

#include <stdio.h>
#include <typeinfo>

class A{
public:
	static void print(){ printf("A\n"); }
	virtual ~A(){ ; }
};

class B:public A{
public:
	static void print(){ printf("B\n"); }
	virtual ~B(){ ; }
};

int main(int argc,char *argv[]){
	B b;
	A *a=&b;
	if(typeid(*a) ==typeid(B) )
		printf("B: %s\n",typeid(*a).name());
	else
		printf("AA\n");

	return 0;
}
相关文章
相关标签/搜索