当前位置: 首页 > news >正文

C++四种类型转换

目录

    • 总结
    • 去常转换:const_cast
    • 静态转换:static_cast
    • 重新解释:reinterpret_cast
    • 动态转换:dynamic_cast

总结

去常转换:const_cast:指针或者引用 去常或者加常
静态转换:static_cast:基本类型转换 子转父安全 父转子不安全 无类型检查
重新解释:reinterpret_cast:任何指针互相转换 不安全
动态转换:dynamic_cast:自转父安全 父转子有类型检查必须有虚方法

去常转换:const_cast

把常量指针或常量引用 转换 为非常量指针或非常量引用
把非常量指针或非常量引用 转换 为常量指针或常量引用
强制转换类型必须是指针*或引用&。

#include<iostream>
using namespace std;
int main()
{const int a = 10;const int& b = 20;//去常int &ra = const_cast<int&>(a);int *pb = const_cast<int*>(&b);cout<<ra<<" "<<*pb<<endl;//加常const int &c = const_cast<const int&>(ra);const int* d = const_cast<const int *>(pb);cout<<c<<" "<<*d<<endl;//int cc = const_cast<int>(a);  错误//int dd = const_cast<int>(b);  错误return 0;
}

静态转换:static_cast

基本类型转换+基本类型指针间转换(void)*

#include<iostream>
using namespace std;
int main()
{//基本类型转换float ft = 12.5f;int a = static_cast<int>(ft);cout<<a<<endl;//输出12//无类型指针转换 不安全 容易出错int number = 100;char *b = static_cast<char*>((void*)&number);int* jieguo = static_cast<int*>((void*)b);cout<<*jieguo<<endl;//输出100return 0;
}

派生类转化为基类(安全) + 基类转化为派生类(不安全)

#include<iostream>
using namespace std;
class Object
{
public:Object(int x = 0):value(x){}void printObject()const {cout<<value<<endl;}
private:int value;
};class Base:public Object
{
public:Base(int x):Object(x+10),num(x){}void printBase()const {cout<<num<<endl;}
private:int num;
};
int main()
{Object obj(10);Base base(20);//上行转换 安全obj = static_cast<Object>(base);obj.printObject();//输出30Object* op = static_cast<Object*>(&base);op->printObject();//输出30//下行转换 不安全//base = static_cast<Base>(obj);//错误Base* bp = static_cast<Base*>(&obj);//输出-1497351504bp->printBase();return 0;
}

重新解释:reinterpret_cast

任何指针都可以转换成其它类型的指针

#include<iostream>
using namespace std;
class Test{};
class Base{};
int main()
{int a = 10;float* fp = reinterpret_cast<float*>(&a);cout<<*fp<<endl;//1.4013e-44Base b;Test* tp = reinterpret_cast<Test*>(&b);//不安全return 0;
}

动态转换:dynamic_cast

从派生类到基类的转换:当已知对象的实际类型时,可以直接转换。
从基类到派生类的转换:在这种情况下,dynamic_cast 会在运行时检查对象的实际类型是否与指定的派生类类型匹配。如果不匹配,dynamic_cast 会返回一个空指针或保持原来的引用不变(对于引用而言)。

注意:
1.dynamic_cast 只能在具有虚函数的类中使用,因为需要运行时类型信息来进行类型检查。因此,如果基类中没有虚函数,dynamic_cast 将无法正常工作。
2.当转换失败时,对于指针,dynamic_cast 返回 nullptr;对于引用,如果转换失败则会抛出 std::bad_cast 异常。

转换成功例子:

#include <iostream>class Base {
public:virtual ~Base() {}virtual void print() { std::cout << "Base\n"; }
};class Derived : public Base {
public:void print() override { std::cout << "Derived\n"; }
};int main() {Derived derivedObj;Base *basePtr = &derivedObj;// 使用 dynamic_cast 进行安全的向下转换Derived *derivedPtr = dynamic_cast<Derived*>(basePtr);if (derivedPtr != nullptr) {derivedPtr->print(); // 输出 "Derived"} else {std::cout << "Conversion failed.\n";}return 0;
}

转换失败例子:

#include <iostream>class Base {
public:virtual ~Base() {}virtual void print() { std::cout << "Base\n"; }
};class Derived : public Base {
public:void print() override { std::cout << "Derived\n"; }
};int main() {Base *basePtr = new Base();Derived *derivedPtr = dynamic_cast<Derived*>(basePtr);if (derivedPtr != nullptr) {derivedPtr->print(); // 不会被调用,因为转换失败} else {std::cout << "Conversion failed.\n";}delete basePtr;return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【课程总结】day19(中):Transformer架构及注意力机制了解
  • 测试类型分类
  • SQLite ORDER BY 语句
  • rust_mac环境安装
  • TypeScript声明文件
  • .ai域名是什么后缀?
  • Java 中的缓冲流
  • Animate软件基础:关于补间动画中的图层
  • 关于香橙派系统烧录,1.1.8或者1.1.10两个版本都无法启动Orangepi5
  • 数据库相关概念大全!
  • 如何优雅地重装系统:使用Ventoy实现系统安装All In One
  • c# 构造器的声明与调用
  • 微信小程序开发:从小程序申请到小程序上线所需要了解的内容
  • 前端使用html2canvas在页面截图并导出,以及截图中含有图片时的跨域问题解决
  • 【前端 19】使用Vue-CLI脚手架构建Vue2项目
  • Apache Spark Streaming 使用实例
  • Consul Config 使用Git做版本控制的实现
  • Intervention/image 图片处理扩展包的安装和使用
  • javascript数组去重/查找/插入/删除
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • Lucene解析 - 基本概念
  • SQL 难点解决:记录的引用
  • vagrant 添加本地 box 安装 laravel homestead
  • Vim 折腾记
  • 阿里云前端周刊 - 第 26 期
  • 多线程 start 和 run 方法到底有什么区别?
  • 两列自适应布局方案整理
  • 算法-图和图算法
  • 中文输入法与React文本输入框的问题与解决方案
  • ​决定德拉瓦州地区版图的关键历史事件
  • ​如何使用QGIS制作三维建筑
  • #WEB前端(HTML属性)
  • (0)Nginx 功能特性
  • (C++二叉树05) 合并二叉树 二叉搜索树中的搜索 验证二叉搜索树
  • (C语言)fread与fwrite详解
  • (LLM) 很笨
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (第30天)二叉树阶段总结
  • (接口自动化)Python3操作MySQL数据库
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (转)winform之ListView
  • .NET Standard 支持的 .NET Framework 和 .NET Core
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .NET/C# 使用反射注册事件
  • .Net6使用WebSocket与前端进行通信
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...
  • @Value获取值和@ConfigurationProperties获取值用法及比较(springboot)
  • [2009][note]构成理想导体超材料的有源THz欺骗表面等离子激元开关——
  • [AutoSar]BSW_Memory_Stack_003 NVM与APP的显式和隐式同步
  • [BUG] Hadoop-3.3.4集群yarn管理页面子队列不显示任务
  • [C++] 如何使用Visual Studio 2022 + QT6创建桌面应用
  • [C++]命名空间等——喵喵要吃C嘎嘎
  • [cocos creator]EditBox,editing-return事件,清空输入框
  • [HCIE] IPSec-VPN (手工模式)