首页 > 编程语言 >c++类型转换与RTTI运行阶段类型识别

c++类型转换与RTTI运行阶段类型识别

时间:2023-07-15 23:31:38浏览次数:45  
标签:类型转换 const 基类 c++ cast 派生类 转换 RTTI 指针

我们都知道C++完全兼容C语言,C语言的转换方式很简单,可以在任意类型之间转换,但这也恰恰是缺点,因为极其不安全,可能不经意间将指向const对象的指针转换成非const对象的指针,可能将基类对象指针转成了派生类对象的指针,这种转换很容易出bug,需要严格审查代码才能消除这种隐患,但是C这种转换方式不利于我们审查代码,且程序运行时也可能会出bug。

所以C++引入的这几种类型转换可以完美的解决上述问题,不同场景下不同需求使用不同的类型转换方式,同时有利于代码审查。

孙悟空都只有七十二变,不能瞎变,所以c++给类型转换做了限制。

c++类型转换与RTTI运行阶段类型识别_派生类

1、static_cast

static_cast

仅当type_name可以被隐式转换为expression所属类型或expression可隐式转换成type_name所属类型时,上述转换才是合法的。

static_cast是用得最多的一类类型转换符,常见的枚举值转成整形,float转整形之类的,都是可以的。

另外,static_cast还可以将派生类指针转换为基类指针,而且一定条件下还能将基类指针转换为派生类指针,且不会报错,只是一些只有派生类才会有的函数、成员变量,转换过来的指针也不会有。

Test test;
    TestDerived derived;
    cout << "----------" << endl;
    Test* tp = static_cast<Test*>(&derived);
    tp->func();
    cout << "-----------------" << endl;
    TestDerived* dp = static_cast<TestDerived*>(&test);
    dp->func();
    dp->speak();
//以下是控制台输出
----------
TestDerived func
-----------------
test func

2、dynamic_cast

c++类型转换与RTTI运行阶段类型识别_派生类_02

dynamic_cast运算符的语法和static_cast一样,但它的作用和static_cast略有区别。

kotlin中有个语法叫 is,本人觉得dynamic_cast就是kotlin中的is

dynamic_cast,一般只用于基类和派生类之间的转换,而且只能用于派生类指针转换成基类指针,不能反向转换。

if (Test* tpp = dynamic_cast<Test*>(&derived)) {
        cout << "devived can cast to test" << endl;
    }
    if (TestDerived* dpp = dynamic_cast<TestDerived*>(&test)) {
        cout << "test can cast to TestDerived" << endl;
    }
//输出
devived can cast to test

如代码所示,如果dynamic_cast转换成功,将返回一个指针,如果转换失败,将返回一个空指针。所以代码中的两个if判断,只有一个生效。看这种调用方式,是不是和kotlin中的 is 很相象呢。

3、const_cast

const_cast运算符,只用于执行一种用途的类型转换,即改变值为const或volatile。

它一般用于去const运算符。但去运算符之后的效果却是难以预料。

const int num = 10;
    const int* tempN = const_cast<const int*>(&num);
    cout << "tempn = " << *tempN << endl;
    int* temppp = const_cast<int*>(tempN);
    *temppp = 20;
    cout << "num = " << num << "  tempn = " << *tempN << "  temppp = " << *temppp << endl;
输出:
tempn = 10
num = 10  tempn = 20  temppp = 20

如上述代码所示,num是const类型的整形值,它的值始终为10,无法更改。这种转换慎用。

4、reinterpret_cast

没有啥特殊场景运用,类似于c语言中的强制转换,一般用得极少。

5、RTTI

c++类型转换与RTTI运行阶段类型识别_运算符_03

RTTI,运行阶段类型识别的简称。

在多态中,比如上面代码中有基类Test和TestDerived,现在有一个Test指针,但不知道这个指针究竟指向的是基类还是派生类,怎么知道指针是指向的哪种对象呢?

这就是RTTI的工作,在运行时判断类型。目前c++中有3个支持RTTI的元素:

  • dynamic_cast,将一个指向基类的指针来生成一个指向派生类的指针,否则,该运算符将返回空指针
  • typeid,返回一个指针对象类型的值
  • type_info,结构存储了有关特定类型的信息

RTTI场景下,父类必须要有虚函数信息,因为RTTI信息存储在虚函数表中。

标签:类型转换,const,基类,c++,cast,派生类,转换,RTTI,指针
From: https://blog.51cto.com/u_15641375/6734280

相关文章

  • lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /home/liuj
     glibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。由于glibc囊括了几乎所有的 UNIX 通行的标准,可以想见其内容包罗万象。而......
  • C++ lambda函数
    一、格式大括号内是变量捕获,小括号内是参数列表。变量捕获的来源都是当前位置“能看得见”的变量。二、变量捕获上图左:将它“能看得见”的变量都按引用捕获。上图右:将它“能看得见”的变量都按值捕获。比如某个lambda表达式在语句块内,但是它全体引用捕获的话可以捕获全局......
  • 数据类型、基本数据类型转换
    基本数据类型整型【byte,short,int,long】byte1 字节short2 字节int4 字节【默认】long8 字节(声明long型常量时,需在常量后加l或L)浮点型【float,double】float4 字节(保留8位有效数字)(声明float型常量时,需在常量后加f或F)double8 字节(保留17位有效数字)【默认】说明:1)浮点数......
  • 类型转换
    类型转换低---------------------------------------------------->高byte,short,char->int->long->float->double强制类型转换高-->低inti=128;bytej=(byte)i;自动类型转换低-->高inti=128;doublej=i;注意不能对布尔值进行转换不能把对象类型转换为不......
  • VS2015 C++代码内存泄漏
    在可能泄漏的文件头部加入下面几行(保证malloc和new的泄漏都可以检测到)#define_CRTDBG_MAP_ALLOC#include<crtdbg.h>#ifdef_DEBUG//重载new运算符#definenewnew(_NORMAL_BLOCK,__FILE__,__LINE__)#endif程序运行起始位置:_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_C......
  • 105.C++初始化
    105.C++初始化C++中变量的初始化有很多种方式,如:默认初始化,值初始化,直接初始化,拷贝初始化,列表初始化。1.默认初始化默认初始化是指定义变量时没有指定初值时进行的初始化操作。默认初始化变量的值与变量的类型与变量定义的位置有关系:1.1内置类型变量对于内置类型变量(如in......
  • 25.什么情况下会发生布尔值的隐式强制类型转换
    25.什么情况下会发生布尔值的隐式强制类型转换?(1)if(..)语句中的条件判断表达式。(2)for(..;..;..)语句中的条件判断表达式(第二个)。(3)while(..)和do..while(..)循环中的条件判断表达式。(4)?:中的条件判断表达式。(5)逻辑运算符||(逻辑或)和&&(逻辑与)左边的操作......
  • Grpc C++使用总结
    Grpc一,安装安装依赖sudoapt-getinstallpkg-configsudoapt-getinstallautoconfautomakelibtoolmakeg++unzipsudoapt-getinstalllibgfalgs-devlibgtest-devsudoapt-getinstallclanglibc++-dev下载gRPCgitclonehttps://github.com/grpc/grpc.gitc......
  • c++ day 9
    今天来学习选择排序选择排序有多种方法下面是方法一:选择排序(SelectionSort)是一种简单但低效的排序算法。它的基本思想是在未排序的部分中选择最小(或最大)的元素,并将其放置在已排序部分的末尾。通过重复这个过程,直到所有元素都排好序为止。下面是选择排序的C++实现示例:#incl......
  • C/C++学生宿舍管理系统[2023-07-14]
    C/C++学生宿舍管理系统[2023-07-14]课程名称:程序设计实践专业班级:学生姓名:学号:任课教师:张闻强学期:2022-2023学年第2学期课程报告任务书题目 学生宿舍管理系统主要内容 用C语言开发一个简单的学生宿舍管理系统。实现宿舍......