C++ RTTI介绍及使用示例(run-time type Identification)

本文深入探讨了C++中的运行时类型识别(RTTI)机制,包括dynamic_cast的向上、向下及交叉转换,以及typeid运算符的使用。通过实例展示了如何安全地进行类型转换,并在多态环境中利用RTTI进行类型检查和对象比较。同时,讨论了RTTI在实现相等运算符等场景中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

一、dynamic_cast

1.向上转换(Casting Up)

2.向下转型(Casting Down)

3.交叉转换

二、typeid

1.typeid的使用示例

 2.typeid运算符使用场景

三、使用RTTI

 


​​​​​​​


前言

运行时类型识别。在有多态行为发生的继承体系中,通过RTTI,程序能够使用基类的指针或者引用来检查这些指针或者引用所指的实际对象的类型。RTTI的实现是由dynamic_cast和typeid运算符来实现的。基类存在虚函数,且子类继承并实现了拥有自己行为的虚函数,那么在基类指针或者引用指向子类对象的时候,就会发生动态绑定,也叫做晚绑定。此时基类指针或者引用的实际类型是子类对象的类型。


 

一、dynamic_cast

1.向上转换(Casting Up)

 向上转型或者说从派生类转换到基类都是可以的,只要不存在二义性。它还可以被隐式的执行。

#include <iostream>

struct A {
    virtual void f() {}
    virtual ~A() {}
    int ma;
};

struct B : A {
    float mb;
    int fb() { return 3; }
};

struct C : A {};

struct D : B, C {};

void f(A a) {}
void g(A& a) {}
void h(A* a) {}

int main()
{
    B b;
    f(b);   //b转换为基类对象发生了切割,
    g(b);
    h(&b);
    return 0;
}

 在这三种情况下,对象b都被隐式转换成类型A的对象。注意,函数f不是多态的,因为多态类型必须以引用或(智能)指针的方式传递。只有当基类存在二义性的时候,向上转换才会失败。例如在这个例子中,我们无法将D 的对象转换到A,因为编译器不知道基类A是从B还是C来的。为了澄清这个二义性,我们需要明确指定中间的转换步骤:先将D对象明确转换为B或者C类型

    D d;
    f((B)d);

 或者我们可以让A作为B和C的虚基类:

#include <iostream>

struct A {
    virtual void f() {}
    virtual ~A() {}
    int ma;
};
struct B : virtual A {
    float mb;
    int fb() { return 3; }
};
struct C : virtual A {};
struct D : B, C {};

void f(A a) {}
void g(A& a) {}
void h(A* a) {}

int main()
{
    D d;
    f(d);
    return 0;
}

 此时,A的成员在D中只会出现一次。在多数情况下,这通常是多重继承的最佳解决方案。

2.向下转型(Casting Down)

向下转型是将指针或者引用转换成子类型的指针或者引用。如果实际引用的对象不是转换的子类型,那么就会导致未定义的行为。因此,只有在绝对必要的条件下才能极为谨慎的使用它。

在上面向上转型的例子中,我们将类型B的对象传递给了引用A& 或者指针A*,在函数g和h中,尽管被引用的对象b是B类型,但是还是不能访问B的成员变量mb和成员函数fb()。在确保函数参数a确实引用了B类型的对象后,可以将a分别向下转型为B& 或者 B*,然后就可以访问mb和fb()了。

在我们准备向程序中引入向下转型之前,必须考虑以下问题:
1、我们如何保证传递给函数的参数确实是派生类的对象?
2、如果不能向下转型我们应该怎么办?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值