0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C++中动态类型的识别

汽车电子技术 来源:嵌入式情报局 作者:情报小哥 2023-02-21 10:24 次阅读

大家好,我是情报小哥~

1、所要解决的问题

在前面的相同专辑文章中,跟大家介绍过虚函数,其中提到了基类的指针可以指向派生类,同时基类的引用也可以成为派生类的别名。

比如是非常经典的例子:

#include 
using namespace std;

class Parent
{
 public:
  virtual void print(void)
  {
   cout<<"Parent print"<class Child: public Parent
{
 public:
  void print(void)
  {
   cout<<"child print"<void Test1(Parent *ptr)
{
    ptr->print();
}

void Test2(Parent& p)
{
    p.print();
}

int main(int argc, char** argv) {
 
    Child child;
    Parent parent;

    Test1(&child);
    Test1(&parent);
    
    Test2(child);
    Test2(parent);
   
    return 0;
}

这样其输出的结果如下:

图片

由于存在虚函数的重写,所以其函数调用都是跟随传入的对象类型,这就是多态;当然如果此例子中Parent类中的print没有virtual虚函数标识,则编译器会认为传入的就是父类指针,从而只会调用父类的成员。

而从Test1或者Test2对象内部看来并不能知道传参是子类型还是父类型:

void Test1(Parent *ptr)
{
    Child* ptrChild = (Child *)ptr;
 
    ptrChild->dosomething(); //调用派生类成员
}

如上代码如果传入的参数是子类对象,那么函数内部用子类类型指向该对象是正常运行的,但如果此时传入的是父类对象,而强制转化为子类指针来使用,则程序就有可能出现未知错误。

所以这里也引出来两个概念:静态类型与动态类型

静态类型: 即编译期间所确定的变量类型;

动态类型: 在运行过程中指针或者引用所指向对象的实际类型。

基于上面的风险,我们急需有一种手段来识别变量的动态类型,以进行相应的处理,我们通常叫其为:RTTI(Run-Time Type Identification,运行时类型识别)

2、进行动态类型识别的方法

进行动态类型识别的方法挺多的,比如利用多态对派生类进行相应ID的标识等等,不过推荐还是采用typeid的方式。

typeid关键字能够获得任意变量的类型信息,也是C++专门提供用于类型识别的方式。

那么下面我们就用一个例程在看看typeid如何使用的:

#include 
#include 

using namespace std;

class Parent
{
 public:
  virtual void print(void)
  {
   cout<<"Parent print"<class Child: public Parent
{
 public:
  void print(void)
  {
   cout<<"child print"<void dosomething(void)
  {
   cout<<"dosomething"<void Test1(Parent *ptr)
{

    if( typeid(*ptr) == typeid(Child) ) //具体使用方式 Child
    {
      Child* ptrChild = dynamic_cast(ptr);

        cout<<"**Dynamic Type: "<<"Child"<dosomething();
        
    } 
    else if( typeid(*ptr) == typeid(Parent) ) //Parent
    {
        cout<<"**Dynamic Type: "<<"Parent"<print();
    }

}

void Test2(Parent& p)
{
    if( typeid(p) == typeid(Child) ) //具体使用方式 Child
    {
       Child& ptrChild = (Child&)p;

        cout<<"**Dynamic Type: "<<"Child"<dosomething();
        
    } 
    else if( typeid(p) == typeid(Parent) ) //Parent
    {
        cout<<"**Dynamic Type: "<<"Parent"<print();
    }
}

int main(int argc, char** argv) {
 
    Child child;
    Parent parent;

    Test1(&child);
    Test1(&parent);
    
    cout<Test2(child);
    Test2(parent);
    
    cout<const type_info& tparent = typeid(parent);
    const type_info& tchild = typeid(child);
 
    cout<name()<name()<return 0;
}

其输出结果如下:

图片

结果看每种指针或者引用的类型均可以动态且正确的获得识别,挺方便的。

最后有几点需要注意下:

1、typeid返回值是名为type_info的标准库类型的对象引用。

2、type_Info的name返回的是一个字符串,且其类名与实际程序中类型不一定是一致的,但是肯定是唯一标识字符串,通过上面输出结果大家也是可以了解到的。

最 后

好了,这里小哥就简单介绍了C++中动态识别机制的使用,本系列文章后续还会更新,记得关注学习哦。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 指针
    +关注

    关注

    1

    文章

    475

    浏览量

    70403
  • 虚函数
    +关注

    关注

    0

    文章

    8

    浏览量

    1675
  • 引用
    +关注

    关注

    0

    文章

    8

    浏览量

    7697
收藏 人收藏

    评论

    相关推荐

    C++小白自学基础教程之c++类型类型检查加强12

    C++
    电子学习
    发布于 :2023年01月12日 21:19:47

    C/C++代码动态测试工具VectorCAST插桩功能演示#代码动态测试 #C++

    C++代码
    北汇信息POLELINK
    发布于 :2024年04月18日 11:57:45

    C/C++的整型常识

    bool类型,C99bool是一个宏,实际为_Bool;    c. CC+
    发表于 10-07 11:12

    JAVA和C++区别

    不支持多重继承,但允许一个类继承多个接口(extends+implement),实现了c++多重继承的功能,又避免了c++的多重继承实现方式带来的诸多不便。 3.数据类型及类 Jav
    发表于 04-11 15:19

    labview调用c++的取地址符对应labview什么数据类型

    调用c++动态链接库,有一个参数是地址类&data,labview对应什么数据类型?急急急!!!!!!!!!!求大神帮忙
    发表于 08-18 11:47

    关于C++的函数重载机制

    ,而且同类型的同名函数能够更好地发挥多种功能.宏观体现就是使用一个函数名字可以完成各种同类型但是不同细节的函数调用(例如,参数的类型不同,或者仅仅是多了一个控制量参数......).所以C++
    发表于 10-01 17:18

    JAVA和C++区别

    不支持多重继承,但允许一个类继承多个接口(extends+implement),实现了c++多重继承的功能,又避免了c++的多重继承实现方式带来的诸多不便。 3.数据类型及类 Jav
    发表于 10-10 14:50

    CC++const的用法比较

    为0)。针对Cconst的上述局限性,C++作出了重大的改进。在C++,可以使用const来定义常数,因为const在编译器的控制范畴内
    发表于 11-11 10:00

    关于C++函数指针的使用

    关于C++函数指针的使用(包含对typedef用法的讨论) (一)简单的函数指针的应用。 //形式1:返回类型(*函数名)(参数表) char (*pFun)(int); char
    发表于 07-13 03:51

    Java和C++的区别

    不支持多重继承,但允许一个类继承多个接口(extends+implement),实现了c++多重继承的功能,又避免了c++的多重继承实现方式带来的诸多不便。 3.数据类型及类 Jav
    发表于 09-13 16:02

    Tensorflow C++动态库编译经验

    Tensorflow C++动态库编译
    发表于 04-10 14:09

    如何利用coder将matlab的程序转换成C/C++

    利用coder将matlab的程序转换成C/C++众所周知,matlab的功能是非常强大的,简便易于操作的工具包更是非常的方便。为机器学习,深度学习,图像处理,语音识别等提供了很大的
    发表于 08-17 06:56

    C++的四种类型转换分别是哪些?C++析构函数的作用是什么

    C++的四种类型转换分别是哪些?C++析构函数的作用是什么?在C语言中关键字static主要
    发表于 12-24 06:57

    如何编译已有的C++去生成可在OpenHarmony系统使用的动态库文件呢

    原有Linux环境下的C++ 项目,可通过在CMakeList文件设置使用的工具链,编译出各平台开发板上可使用的so文件。请问,我现在在Hi3516开发板上,烧录OpenHarmony V3.1Beta版本的标准系统,该如何编译已有的
    发表于 03-16 10:42

    请问C++项目如何编译成可在OpenHarmony3.1环境下使用的动态so文件?

    以前的Linux环境的C++项目,可以通过在CMakeList文件设置使用的工具链,编译出各个开发平台下可以使用的so文件。请问,我现在在开发平台上,烧录OpenHarmon V3.1版本的Hi3516,系统可以编译使用已有C++
    发表于 06-06 16:41