C++_virtual虚函数, 多态, typeid, RTTI, dynamic_cast, typeid,动态类型

本文详细探讨了C++中的动态类型、虚函数分类、多态的两种使用方式,以及dynamic_cast的效率和多态数据获取。重点讲解了虚函数表、RTTI(运行时类型信息)中的typeid和dynamic_cast的用法,强调了多态类的析构函数必须是虚函数的重要性。文章还阐述了动态类型的概念,指出只有在类包含至少一个虚函数时,才会存在动态类型,并介绍了如何通过RTTI获取对象的实际类型。

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

动态/静态类型

静态类型, 在 程序中声明时, 就已经确定了, 而且用于不会改变
动态类型, 他只针对指针, 可以变化 通过赋值来改变

(非指针)变量, 他只有 (静态类型) Foo f; 则f 的静态类型为Foo, 没有动态类型

(指针)变量, 他 既有(静态), 也有 (动态)类型
Fa * fa; (此时, fa的静态类型为: Fa *, 动态类型为 无 (或者说, 没有动态类型))

fa = new Son1; (此时, fa 的动态类型为 Son1 *)

fa = new Son2; (此时, fa 的动态类型为 Son2 *)

fa = nullptr; (此时, fa 又没有动态类型了)

virtual函数分类

一般, virtual函数分为: (pure virtual 纯虚函数, 即子类必须实现)
(impure virtual 非纯虚函数, 若子类实现 而覆盖, 否则使用 父类实现的版本)

多态的2种使用

  • 指针
    Son s;
    Fa * fa = &s;
    
    fa->func(); ' 会调用到: s.func() '
    
  • 引用
    Son s;
    Fa & fa = s; ' 或: const Fa & fa = Son();   <只有const引用, 可以绑定 临时对象> '
    
    fa.func(); ' 会调用到: s.func() '
    

对于, dynamic_cast (即获取他的子类对象), 也有2个方式:

  • 指针
    Fa * fa = new XX;
    Son * son = dynamic_cast<Son *>( fa);
    if( son != nullptr){
         
    	cout << "success cast";
    }
    
  • 引用
    try{
         
    	Fa * fa = new XX; 
        Son & son = dynamic_cast< Son &>( *fa);
    }
    catch( const std::bad_cast &){
         
    	cout << "failed cast";
    }
    
    与指针方式不同, (指针可以通过返回值是否是nullptr来判断, 因为如果转换失败则返回nullptr)
    但引用方式, 转换失败, 会throw异常

dynamic_cast

效率

dynamic_cast的效率很慢!!!

dynamic_cast的原理是: 基于class名称的 字符串比较
即, 他会将内存对象继承体系里的每个子类, 进行strcmp匹配

多态数据获取

Fa * fa = new Son 我们令, 这个new Son对象 为 son
这个fa

  • fa->data, 一定对应为: son->Fa::data, 而不是son->data!!!
  • fa->func, (如果func为虚函数, 且Son也有自己的实现: 则fa->func会调用son->func()) (否则: fa->func()会调用son->Fa::func())

即, 我们可能会误以为: 多态, 只是针对func的多态; 对于数据data, 并无法使用多态

简单来说, 这种说法是正确的;

但是, 借助dynamic_cast, 可以实现 对data的多态!!!

Fa * fa = new Son; 我们令, 这个new Son对象 为 son, 且: son->data = 1, son->Fa::data = 0

  • fa->data 可以来获取: son->Fa::data
  • 那么: son->data 如何通过 fa来获取呢??
    Son * s = dynamic_cast< Son *>( fa);, 此时, 这个s对象, 和上面的son对象, 是完全相同的!!
    自然, s->data 就是 son->data

虚函数/ 多态类

如何判断, 一个类是否是(多态类)呢

  • 方法1:
    • 当该类不是子类: 如果, 该类中 有>=1个 虚函数, 虚函数: 虚成员函数 或 虚析构函数, 则该类是多态类
    • 当该类是子类: 如果, 其父类是多态类, 则该类是多态类
  • 方法2: 通过dynamic_cast, 下面会谈到

如果一个类有虚成员函数, 则你必须显式的 将他的 析构函数, 也写成 虚函数!!! 下面会解释为什么

即, 只要是多态类,则你必须显式的 将他的 析构函数 写成 虚函数


虚函数, 在类内 最好是声明, 不要在类中实现出来!!!


dynamic_cast 与 多态类

dynamic_cast< A *>( B *)
要求:

  • B类, 必须是 多态类, 否则报错!!!

dynamic_castA类, 没有任何限制!!! A 和 B, 可以是完全毫无任何关系!!! 至少编译通过; 只是会强转失败而已


' 继承关系:  SSON -> SON -> FA '
FA * ptr = new SSON;

using T = FA / SON / SONN;
T 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值