详解C++中常用的四种类型转换方式

目录
  • 1.静态类型转换:static_cast(exp)
  • 2.动态类型转换:dynamic_cast(exp)
  • 3.常类型转换:const_case(exp)
  • 4. 解释类型转换: reinterpret_cast(exp)

1.静态类型转换:static_cast(exp)

1.1静态类型转换主要用于两种转换环境

1.1.1 C++内置类型的转换:与C风格强转类似。

与c相同的地方:

#include <iostream>

using namespace std;

int main()
{
    double a=3.14;

    cout << static_cast<int>(a) << endl;

    return 0;
}

不同的地方就是使用static_cast不能强转内置类型指针的,这点可以避免C风格中的越界问题。

如图所示:

1.1.2当有继承关系存在时的强转:

如果使用static_cast 由子类向父类转型,向上转型,天然安全安全。(应为子类的空间肯定比父类的空间大,子类是在继承父类的空间上面开辟),代码如下:

#include <iostream>

using namespace std;

class A
{
public:
    int a=100;

    void Ashow_info()
    {
        cout<<this->a<<endl;
    }
};

class B:public A
{
public:
    int a=200;
    int b=300;
    int c=400;
    void Bshow_info()
    {
        cout<<this->a<<this->b<<this->c<<endl;
    }
};

int main()
{
   B* a=new B;
   static_cast<A*>(a)->Ashow_info();

    return 0;
}

结果图:

我们可以通过子类安全的访问到父类中的a值。

如果使用static_cast 由父类向子类转型,向下转型,是不安全。

那么何时不安全?何时安全?

不安全的情况介绍:

#include <iostream>

using namespace std;

class A
{
public:
    int a=100;

    void Ashow_info()
    {
        cout<<this->a<<endl;
    }
};

class B:public A
{
public:
    int a=200;
    int b=300;
    int c=400;
    void Bshow_info()
    {
        cout<<this->a<<this->b<<this->c<<endl;
    }
};

int main()
{
   A* a=new A;
   static_cast<B*>(a)->Bshow_info();

    return 0;
}

结果图:

如图所示结果中并没有出现本应该打出的200,300,400,这就是不知道子类空间是否被开辟而向下访问造成的结果。

安全的情况:

#include <iostream>

using namespace std;

class A
{
public:
    int a=100;

    void Ashow_info()
    {
        cout<<this->a<<endl;
    }
};

class B:public A
{
public:
    int a=200;
    int b=300;
    int c=400;
    void Bshow_info()
    {
        cout<<this->a<<this->b<<this->c<<endl;
    }
};

int main()
{
   A* a=new B;
   static_cast<B*>(a)->Bshow_info();

    return 0;
}

结果图:

如图所示,此时我们可以打出200,300,400,等数值,说明当我们知道子类空间被开辟时候,就可以安全的向下访问。

2.动态类型转换:dynamic_cast(exp)

2.1概念

动态类型转换是依赖于虚函数的与继承关系,没有虚函数,就无法使用动态类型转换。dynamic_cast是一个安全类型转换,因为他是依赖于函数实现动态转型。因为虚表中的第一个Slot位置保存了类型运行识别信息。

注意使用的条件为:1)要有继承关系 2)要有虚函数。

这个虚表的结构:

2.2代码举例说明

#include <iostream>

using namespace std;

class A
{
public:

    virtual void show_info()
    {
        cout<<"我是父亲"<<endl;
    }
};

class B:public A
{
public:

    void show_info()
    {
        cout<<"我是儿子"<<endl;
    }
};

int main()
{
   A* a=new B;
   dynamic_cast<B*>(a)->show_info();

    return 0;
}

结果图:

3.常类型转换:const_case(exp)

就是用来修改const修饰的常引用和常指针的转换方式

3.1代码说明

#include <iostream>

using namespace std;

int main()
{
    const int& a=100;

    const_cast<int&>(a)=200;

    cout<<a<<endl;

    return 0;
}

结果图:

由图可知我们修改了常引用的数值。

4. 解释类型转换: reinterpret_cast(exp)

4.1概念

这要类型转换方式,是可以庆用于任何类型,他的底层的实现就是对底层二进制数据的一个拷贝。所以也是一个不安全的强转。

4.2由于这个一般都不用,从我们最有可能的会用到的情况下抽出来一种,代码如下:

当我们想把一个数的地址,用10进制的表达出来的时候,如下,光一个int 是装不下地址的十进制,所以系统就会给我们报错。

这个时候reinterpert_cast就起到了作用,我们可以把他转为long long类型,如下:

#include <iostream>

using namespace std;

int main()
{
  int a=10;

  int *p=&a;

  cout<<reinterpret_cast<long long>(p)<<endl;
    return 0;
}

结果图:

到此这篇关于详解C++中常用的四种类型转换方式的文章就介绍到这了,更多相关C++类型转换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++强制类型转换(static_cast、dynamic_cast、const_cast、reinterpret_cast)

    目录 1. c强制转换与c++强制转换 2. static_cast.dynamic_cast.const_cast.reinterpret_cast dynamic_cast const_cast reinterpret_cast 3. c++强制转换注意事项 1. c强制转换与c++强制转换 c语言强制类型转换主要用于基础的数据类型间的转换,语法为: (type-id)expression//转换格式1 type-id(expression)//转换格式2 c++除了能使用c语言的强制类型转

  • C++ 强制类型转换详解

    目录 一.C强制转换 二.C++强制转换 1.static_cast 静态转换(编译时检查) 2.const_cast 常量转换 3.reinterpret_cast 重新解释转换 4.dynamic_cast 动态转换(运行时检查) 三.要点总结 一.C强制转换 C语言中的强制转换主要用于普通数据类型.指针的强制转换,没有类型检查,转换不安全, 语法为: (type-id)expression//转换格式1 type-id(expression)//转换格式2(基本已经不用了) 二.C++强制

  • C++实例讲解四种类型转换的使用

    目录 C++类型转换 C语言风格的转换 C++风格的类型转换 static_cast reinterpret_cast const_cast dynamic_cast 小结 C++类型转换 C语言风格的转换 C语言提供了自己的一套转换规则,有好处也有坏处. C语言的风格:(type_name)expression; C语言提供了隐式类型转换和显式类型转换.显式类型转换一般也叫做强转,隐式类型转换编译器完成,如果转换不了就报错. 而C语言类型转换的风格好处就是简单,缺陷比如转换的可视性差,显式类型

  • C++超详细讲解强制类型转换

    目录 1 C 强制类型转换 2 C++ 强制类型转转 1 C 强制类型转换 C 方式的强制类型转换的用法如下代码所示: (Type)(Expression) Type:需要转换成的类型 Expression:对其进行转换 e.g. int v = 0x12345; // 将 int 类型的变量转换成 char 类型 char c = char(v); C 方式的强制类型转换存在如下问题: 过于粗暴:任意类型之间都可以进行转换,编译器很难判断其正确性 typedef void(PF)(int);

  • C++强制类型转换的四种方式

    目录 1 C++类型转换本质 1.1 自动类型转换(隐式) 1.2 强制类型转换(显式) 1.3 类型转换的本质 1.4 类型转换的安全性 2 四种类型转换运算符 2.1 C语言的强制类型转换与C++的区别 3 static_cast 4 reinterpret_cast 5 const_cast 6 dynamic_cast 6.1 向上转型(Upcasting) 6.2 向下转型(Downcasting) 1 C++类型转换本质 1.1 自动类型转换(隐式) 利用编译器内置的转换规则,或者用

  • C++超详细讲解强制类型转换的用法

    目录 static_cast dynamic_cast const_cast reinterpret_cast static_cast static_cast<type-id>(expression) 将 expression 转换为 type-id 类型.static_cast 是静态类型转换,发生在编译期.这种转换不会进行运行时的动态检查(RTTI),因而这种转换可能是不安全的.static_cast 典型应用场景如下: 1. 类的层级结构中,基类和子类之间指针或者引用的转换. 上行转换(

  • 详解C++中常用的四种类型转换方式

    目录 1.静态类型转换:static_cast(exp) 2.动态类型转换:dynamic_cast(exp) 3.常类型转换:const_case(exp) 4. 解释类型转换: reinterpret_cast(exp) 1.静态类型转换:static_cast(exp) 1.1静态类型转换主要用于两种转换环境 1.1.1 C++内置类型的转换:与C风格强转类似. 与c相同的地方: #include <iostream> using namespace std; int main() {

  • 详解Spring中bean的几种注入方式

    首先,要学习Spring中的Bean的注入方式,就要先了解什么是依赖注入.依赖注入是指:让调用类对某一接口的实现类的实现类的依赖关系由第三方注入,以此来消除调用类对某一接口实现类的依赖. Spring容器中支持的依赖注入方式主要有属性注入.构造函数注入.工厂方法注入.接下来将为大家详细介绍这三种依赖注入的方式以及它们的具体配置方法. 1.属性注入 属性注入即通过setXXX( )方法注入bean的属性值或依赖对象.由于属性注入方式具有可选择性和灵活性高的特点,因此它也是实际开发中最常用的注入方式

  • 详解VUE中常用的几种import(模块、文件)引入方式

    1 引入第三方插件 import echarts from 'echarts' 2 引入工具类 第一种是引入单个方法 import {axiosfetch} from './util'; 下面是写法,需要export导出 export function axiosfetch(options) { } 第二种  导入成组的方法 import * as tools from './libs/tools' 其中tools.js中有多个export方法,把tools里所有export的方法导入 vue中

  • 详解Android中Fragment的两种创建方式

    fragment是Activity中用户界面的一个行为或者是一部分.你可以在一个单独的Activity上把多个Fragment组合成为一个多区域的UI,并且可以在多个Activity中再使用.你可以认为fragment是activity的一个模块零件,它有自己的生命周期,接收它自己的输入事件,并且可以在Activity运行时添加或者删除. 两个概念:Fragment.宿主 fragment的生命周期直接受其宿主activity的生命周期的影响.例如,一旦activity被暂停,它里面所有的fra

  • 详解vue 路由跳转四种方式 (带参数)

    1.  router-link 1. 不带参数 <router-link :to="{name:'home'}"> <router-link :to="{path:'/home'}"> //name,path都行, 建议用name // 注意:router-link中链接如果是'/'开始就是从根路由开始,如果开始不带'/',则从当前路由开始. 2.带参数 <router-link :to="{name:'home', para

  • 详解Java停止线程的四种方法

    一.线程停止基础知识 interrupted(): 测试当前线程是否已经中断.该方法为静态方法,调用后会返回boolean值.不过调用之后会改变线程的状态,如果是中断状态调用的,调用之后会清除线程的中断状态. isInterrupted(): 测试线程是否已经中断.该方法由对象调用 interrupt(): 标记线程为中断状态,不过不会中断正在运行的线程. stop(): 暴力停止线程.已弃用. 二.停止线程方法1:异常法停止 线程调用interrupt()方法后,在线程的run方法中判断当前对

  • 详解基于redis实现的四种常见的限流策略

    目录 一.引言 二.固定时间窗口算法 三.滑动时间窗口算法 四.漏桶算法 五.令牌桶算法 一.引言 在web开发中功能是基石,除了功能以外运维和防护就是重头菜了.因为在网站运行期间可能会因为突然的访问量导致业务异常.也有可能遭受别人恶意攻击 所以我们的接口需要对流量进行限制.俗称的QPS也是对流量的一种描述 针对限流现在大多应该是令牌桶算法,因为它能保证更多的吞吐量.除了令牌桶算法还有他的前身漏桶算法和简单的计数算法 下面我们来看看这四种算法 二.固定时间窗口算法 固定时间窗口算法也可以叫做简单

  • 详解Python中常用的图片处理函数的使用

    目录 cvtColor函数 split()和merge() threshold()函数 自定义threshold函数进行二值化 色度函数applyColorMap cvtColor函数 这个函数有两个参数 1,src 要进行变换的原图像 2,code 转换代码标识 例子: import cv2 image=cv2.imread("ddd.jpg") image1=cv2.cvtColor(image,cv2.COLOR_BGR2BGRA) cv2.imshow(""

  • 详解flutter中常用的container layout实例

    目录 简介 Container的使用 旋转Container Container中的BoxConstraints 总结 简介 在上一篇文章中,我们列举了flutter中的所有layout类,并且详细介绍了两个非常常用的layout:Row和Column. 掌握了上面两个基本的layout还是不够的,如果需要应付日常的layout使用,我们还需要掌握多一些layout组件.今天我们会介绍一个功能强大的layout:Container layout. Container的使用 Container是一

  • 详解Nginx 和 PHP 的两种部署方式的对比

    详解Nginx 和 PHP 的两种部署方式的对比 2种部署方式简介 第一种 前置1台nginx服务器做HTTP反向代理和负载均衡 后面N太服务器的Nginx做Web服务,并调用php-fpm提供的fast cgi服务 此种部署方式最为常见,web服务和PHP服务在同一台服务器上都有部署 第二种 前置1台nginx服务器做Web服务 后面服务器只部署php-fpm服务,供nginx服务器调用 前置1台nginx服务器,在调用后面多例php-fpm服务时,也可以做到负载均衡 如下图 : 对比 从系统

随机推荐