本文介绍: RTTI(Run Time Type Identification)即通过运行类型识别程序能够使用基类指针引用检查着这些指针引用所指的对象的实际派生类型。

RTTI

概念

RTTI(Run Time Type Identification)即通过运行时类型识别程序能够使用基类指针引用来检
查着这些指针引用所指的对象的实际派生类型。

原因

C++是一种静态
语言。其数据类型是在编译期就确定的,不能在运行更改。然而由于面向对象程序设计多态性
要求,C++中的指针或引用(Reference)本身的类型,可能与它实际代表(指向或引用)的类型并不一致。
有时我们需要一个多态指针转换其实指向对象的类型,就需要知道运行时的类型信息,这就产生
运行时类型识别的要求。

在C++中为了支持 RTTI 提供了两个操作符

  1. typeid 操作符,它在程序中可用于获取一个表达式的类型 ;

查询类型的信息, 类型。它指出指针或引用指向对象的实际派生类型。

  1. dynamic_cast 操作可以用来一个类类型对象的指针,转换成同一类层次结构中的其他类的指 针 ,同时也可以用它把一个类类型对象的左值,转换成同一类层次结构中其他类的引用。

dynamic_casttypeid 操作符的操作数的类型 ,必须是带有一个多个虚拟函数的类类型。 即对于 带有虚拟函数的类而言 RTTI 操作符是运行时刻的事件 ,而对于其他类而言,它只是编译时刻的事件

1.typeid

C++顶层const底层const

c++ primer里的原文:

指针本身是一个对象,它又可以指向另外一个对象。因此,指针本身是不是常量以及指针所指的是不是一个常量就是两个相互独立问题。用名词顶层 consttoplevel const表示指针本身是个常量,而用名词底层 constlowlevel const表示指针所指的对象是一个常量
更一般的,顶层 const 可以表示任意的对象是常量,这一点对任何数据类型都适用,如算术类型、类、指针等。底层 const 则与指针和引用等复合类型的基本类型部分有关比较特殊的是,指针类型既可以是顶层 const 也可以是底层const,这一点和其他类型相比区别明显∶

举例:
int a = 0; 
const int *const p= a; //第二个const其实const p表示p这个指针本身是常量,即其中存放地址不能变。
//第一个const,其实是 const *p表示*p不变,即其指向的对象不变。
//所以可以认为在第一个const是底层const,第二个const是顶层const.
const int* p = nullptr; //  底层const
int* const q = nullptr; //  顶层const

####所有情况下, typeid忽略顶层的 cv 限定符 。

int main()
{
    const int a = 10;
    int b = 20;
    int*const pb = &b;
    const int* const pa = &a;
    cout<<"a : "<<typeid(a).name()<<endl;
    cout<<"b : "<<typeid(b).name()<<endl;
    cout<<"pa : "<<typeid(pa).name()<<endl;
    cout<<"*pa : "<<typeid(*pa).name()<<endl;
    cout<<"pb : "<<typeid(pb).name()<<endl;
    cout<<"*pb : "<<typeid(*pb).name()<<endl;
    
    return 0;
}

用于多态类型的表达式时,typeid 表达式的求值可能涉及运行时开销(虚表查找),其他情况下
typeid 表达式都在编译解决

eg: 继承+多态运行时开销
class Object
{
private:
 int value;
public:
 Object(int x = 0) :value(x) {}
 virtual ~Object() {}
};
class Base :public Object
{
private:
 int num;
public:
 Base(int x = 0) :num(x) {}
 ~Base() {}
};

int main()
{
 Object obj;
 Base base;
 Object* op = &amp;base;
 Base* bp = &amp;base;
 cout << typeid(op).name() << " t" << typeid(*op).name() << endl;
 cout << typeid(bp).name() << " t" << typeid(*bp).name() << endl; 
}

运行结果

在这里插入图片描述

图解:

对于含有虚函数的继承关系,对基类指针进行解引用或基类引用时:涉及运行时开销,需要查虚表

typeid(*op).name(); //查虚表

typeid(*bp).name(); //查虚表

void fun(Object&amp; s); //查虚表
{
cout << typeid(s).name() << endl;
}

fun(base); //查虚表

在C++中,提供了一个类,管理这个全局数据结构这个数据结构就是type_info;
typeid 操作符实际上返回一个类型为 type_info 的类对象。

原文地址:https://blog.csdn.net/qq_63282188/article/details/134749415

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_30318.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注