一文说清C++类型转换操作符(cast operator)

一 前言

大家在编程时,一定会遇到要做类型转换的应用场景。
但是,C风格的类型转换太强大,太危险,它允许将一个给定类型转换成我们想要的任何其他类型。
所以在C++中,提供了一些更安全和更明确的类型转换操作符,来进行类型转换。
以下是关于各种类型转换的扩展示例,以展示它们的用法和特点,包括如下几种:

  • dynamic_cast
  • static_cast
  • const_cast
  • reinterpret_cast

二 各类转换说明

1 dynamic_cast

dynamic_cast 用于多态类型的安全转换。它通过运行时类型识别(RTTI)来确保转换的有效性。

#include <iostream>
#include <exception>

class Base {
public:
    virtual ~Base() {} // 确保 Base 是一个多态类型
};

class Derived : public Base {
public:
    void show() {
        std::cout << "Derived class" << std::endl;
    }
};

class AnotherClass {};

int main() {
    Base* basePtr = new Derived(); // Base 指针指向 Derived 对象

    // 使用 dynamic_cast 进行安全转换
    if (Derived* derivedPtr = dynamic_cast<Derived*>(basePtr)) {
        derivedPtr->show(); // 成功转换,调用 Derived 的方法
    } else {
        std::cout << "Failed to cast Base to Derived" << std::endl;
    }

    // 尝试将 Base 指针转换为 AnotherClass 指针
    try {
        AnotherClass* anotherPtr = dynamic_cast<AnotherClass*>(basePtr); // 无效转换
        if (anotherPtr == nullptr) {
            throw std::bad_cast(); // 抛出 bad_cast 异常
        }
    } catch (const std::bad_cast& e) {
        std::cout << "Caught bad_cast exception: " << e.what() << std::endl;
    }

    delete basePtr; // 释放内存
    return 0;
}

2 static_cast

static_cast 用于非多态类型的转换,没有运行时检查。

#include <iostream>

class Base {
public:
    virtual ~Base() {}
};

class Derived : public Base {
public:
    void show() {
        std::cout << "Derived class" << std::endl;
    }
};

int main() {
    Base* basePtr = new Derived(); // Base 指针指向 Derived 对象

    // 使用 static_cast 进行转换
    Derived* derivedPtr = static_cast<Derived*>(basePtr);
    derivedPtr->show(); // 成功转换,调用 Derived 的方法

    delete basePtr; // 释放内存
    return 0;
}

3 const_cast

const_cast 用于去除对象的常量性(constness)。

#include <iostream>

void modifyValue(const int* ptr) {
    int* nonConstPtr = const_cast<int*>(ptr); // 去除常量性
    *nonConstPtr = 20; // 修改值
}

int main() {
    int value = 10;
    const int* constPtr = &value;

    std::cout << "Before: " << value << std::endl;
    modifyValue(constPtr);
    std::cout << "After: " << value << std::endl; // 输出修改后的值

    return 0;
}

4 reinterpret_cast

reinterpret_cast 用于进行低级别的类型转换,通常用于指针和整型类型之间的转换。
这是C++中最灵活也是最危险的类型转换操作,仅次于传统的C语言转换操作符。

#include <iostream>

int main() {
    int num = 65;
    // 将整型转换为字符指针
    char* charPtr = reinterpret_cast<char*>(&num);

    std::cout << "Integer value: " << num << std::endl;
    std::cout << "Interpreted as char: " << *charPtr << std::endl; // 输出对应的字符

    // 将指针转换回整型
    int* intPtr = reinterpret_cast<int*>(charPtr);
    std::cout << "Interpreted back to int: " << *intPtr << std::endl; // 输出回到整型值

    return 0;
}

三 总结

  1. dynamic_cast: 适用于多态类型的安全转换,包含运行时检查。
  2. static_cast: 用于非多态类型的转换,不进行运行时检查。
  3. const_cast: 用于去除常量性,可以修改原本是常量的对象。
  4. reinterpret_cast: 提供指针和整型之间的低级别类型转换,灵活但风险较高。

使用这些类型转换操作符时,大家需要谨慎,以确保类型安全和程序的可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/916626.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

音视频入门基础:MPEG2-TS专题(5)——FFmpeg源码中,判断某文件是否为TS文件的实现

一、引言 通过FFmpeg命令&#xff1a; ./ffmpeg -i XXX.ts 可以判断出某个文件是否为TS文件&#xff1a; 所以FFmpeg是怎样判断出某个文件是否为TS文件呢&#xff1f;它内部其实是通过mpegts_probe函数来判断的。从《FFmpeg源码&#xff1a;av_probe_input_format3函数和AVI…

微服务day07

MQ高级 发送者可靠性&#xff0c;MQ的可靠性&#xff0c;消费者可靠性。 发送者可靠性 发送者重连 连接重试的配置文件&#xff1a; spring:rabbitmq:connection-timeout: 1s # 设置MQ的连接超时时间template:retry:enabled: true # 开启超时重试机制initial-interval: 10…

艾体宝干货丨微突发流量检测与分析:IOTA让网络监控更精准

网络流量中的微突发问题常常难以察觉&#xff0c;但它们可能对网络性能产生显著影响。这篇文章深入探讨了如何利用IOTA来捕捉和分析微突发&#xff0c;帮助您快速有效地解决网络中的突发流量问题。 什么是微突发&#xff08;Microburst&#xff09;流量&#xff1f; 微突发是…

SQL 审核在 CloudQuery 的四大场景应用

数据库作为数据的核心载体&#xff0c;其安全性和稳定性对业务的影响至关重要。而在我们日常业务中&#xff0c;SQL 编写不当是引起数据库故障的一个重要原因&#xff0c;轻则影响数据库性能&#xff0c;重则可能直接导致「雪崩」。因此&#xff0c;SQL 审核作为 SQL 代码投入生…

uniapp: 微信小程序包体积超过2M的优化方法

一、问题描述 在使用uniapp进行微信小程序开发时&#xff0c;经常会遇到包体积超过2M而无法上传&#xff1a; 二、解决方案 目前关于微信小程序分包大小有以下限制&#xff1a; 整个小程序所有分包大小不超过 30M&#xff08;服务商代开发的小程序不超过 20M&#xff09; 单个…

Node.Js+Knex+MySQL增删改查的简单示例(Typescript)

数据库: CREATE DATABASE MyDB; CREATE TABLE t_users (user_id int(11) NOT NULL,user_name varchar(10) NOT NULL ) ENGINEInnoDB DEFAULT CHARSETutf8; 项目结构: package.json如下&#xff0c;拷贝并替换你们本地的package.json后运行 npm install 命令安装所需要的依赖。…

fastadmin多个表crud连表操作步骤

1、crud命令 php think crud -t xq_user_credential -u 1 -c credential -i voucher_type,nickname,user_id,voucher_url,status,time --forcetrue2、修改控制器controller文件 <?phpnamespace app\admin\controller;use app\common\controller\Backend;/*** 凭证信息…

【论文阅读】利用SEM二维图像表征黏土矿物三维结构

导言 在油气储层研究中&#xff0c;黏土矿物对流体流动的影响需要在微观尺度上理解&#xff0c;但传统的二维SEM图像难以完整地表征三维孔隙结构。常规的三维成像技术如FIB-SEM&#xff08;聚焦离子束扫描电子显微镜&#xff09;虽然可以获取高精度的3D图像&#xff0c;但成本…

JavaScript 中的 undefined 、null 与 NaN :概念解析与对比

文章目录 &#x1f4af;前言&#x1f4af;undefined1. 什么是 undefined2. undefined 的使用场景3. undefined 的特性 &#x1f4af;null1. 什么是 null2. null 的使用场景3. null 的特性 &#x1f4af;NaN1. 什么是 NaN2. NaN 的使用场景3. NaN 的特性 &#x1f4af;三者的区别…

C++编程技巧与规范-类和对象

类和对象 1. 静态对象的探讨与全局对象的构造顺序 静态对象的探讨 类中的静态成员变量(类类型静态成员) 类中静态变量的声明与定义&#xff08;类中声明类外定义&#xff09; #include<iostream> using namespace std;namespace _nmspl {class A{public:A():m_i(5){…

python遇到问题

1&#xff0c;BeautifulSoup lxml 解析器安装 问 1&#xff0c;BeautifulSoup lxml 解析器安装2&#xff0c;BeautifulSoup 如何引入第三方库 BeautifulSoup lxml&#xff0c;默认是导入的是python内置的解析器答1 1. 安装 Python 和 pip 确保你已经安装了 Python 和 pip。你…

async 和 await的使用

一、需求 点击按钮处理重复提交&#xff0c;想要通过disabled的方式实现。 但是点击按钮调用的方法里有ajax、跳转、弹窗等一系列逻辑操作&#xff0c;需要等方法里流程都走完&#xff0c;再把disabled设为false&#xff0c;这样下次点击按钮时就可以继续走方法里的ajax等操作…

MacOS下,如何在Safari浏览器中打开或关闭页面中的图片文字翻译功能

MacOS下&#xff0c;如何在Safari浏览器中打开或关闭页面中的图片文字翻译功能 在Mac上的Safari浏览器中&#xff0c;可以通过实况文本功能来实现图片中的文本翻译。关闭步骤具体步骤如下&#xff1a; 在浏览器地址栏&#xff0c;鼠标右击翻译按钮&#xff0c;然后点击“首选…

31.2 DOD压缩和相关的prometheus源码解读

本节重点介绍 : 时序数据时间的特点DOD压缩原理讲解dod压缩过程讲解dod压缩 prometheus源码解读 时序数据时间的特点 持续采集采集间隔固定&#xff0c;如prometheus配置job中的scrape_interval参数每隔15秒采集一次 - job_name: node_exporterhonor_timestamps: truescrape…

推荐一款好用的ios传输设备管理工具:AnyTrans for iOS

AnyTrans for iOS是一款好用的ios传输设备管理工具&#xff0c;可以方便用户对iphone、ipad、ipod中的文件进行管理操作&#xff0c;可以方便用户在电脑上进行各类文件的管理操作&#xff0c;支持联系人、视频、音频、短信、图片等文件的导入&#xff0c;软件支持双向传输和浏览…

快速利用c语言实现线性表(lineList)

线性表是数据结构中最基本和简单的一个&#xff0c;它是n的相同类型数据的有序序列&#xff0c;我们也可以用c语言中的数组来理解线性表。 一、线性表声明 我们定义一个线性表的结构体&#xff0c;内部有三个元素&#xff1a;其中elem是一个指针&#xff0c;指向线性表的头&am…

计算机毕业设计Python+CNN卷积神经网络股票预测系统 股票推荐系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

QT QLineEdit失去焦点事件问题与解决

本文介绍如何获得QLineEdit的失去焦点事件和获得焦点的输入框也会触发失去焦点事件的问题&#xff01; 目录 一、QLineEdit获得失去焦点事件 1.自定义类继承自QLineEdit 2.重写 focusOutEvent 3.使用 二、失去焦点事件问题 1.问题描述 2.问题解决 三、源码分享 lineed…

vscode执行npm install报错

npm install一直提示报错 以管理员身份运行vscode&#xff0c;如果每次觉得很麻烦可以做如下修改&#xff1a;

【算法】树状数组

前言 众所周知&#xff0c;通过前缀和&#xff0c;我们可以很快的在一个很大的数组中求出区间和&#xff0c;但是如果想要去修改数组中的一个数的值&#xff0c;前缀和就无法实现。所以来学习一个新的数据结构&#xff1a;树状数组 &#xff08;文章中关于树状数组的截图来自于…