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

C++ 类型转换 包括C风格的转换、static_cast、const_cast、reinterpret_cast、dynamic_cast、模板特化等

C++ 类型转换 包括C风格的转换、static_cast、const_cast、reinterpret_cast、dynamic_cast、模板特化等

flyfish

0. 隐式转换(Implicit Conversions)

隐式转换是编译器自动进行的类型转换,通常在需要将一个类型转换为另一个类型以匹配函数参数、赋值或比较时发生。
示例:

#include <iostream>void printInt(int i) {std::cout << "Implicitly converted to int: " << i << std::endl;
}int main() {char c = 'A'; // char类型printInt(c); // char类型隐式转换为int类型return 0;
}

在这个例子中,字符类型char被隐式转换为整数类型int以匹配函数参数类型。

1. C-Style Casts (C风格的转换)

C风格的转换使用括号进行类型转换。这种转换方式功能强大,但缺乏类型安全性,可能导致难以发现的错误。
示例:

#include <iostream>int main() {double d = 9.99;int i = (int)d; // C-Style Caststd::cout << "C-Style Cast: " << i << std::endl;return 0;
}

2. C++风格的转换运算符

static_cast

static_cast用于在相关类型之间进行显式转换,例如从基类指针转换为派生类指针,或者从int转换为double
示例:

#include <iostream>int main() {double d = 9.99;int i = static_cast<int>(d);std::cout << "static_cast: " << i << std::endl;return 0;
}
const_cast

const_cast用于移除或添加const属性。

  • 移除 const 属性:使用 const_castconst 对象转换为非 const 对象,通常用于将 const 对象传递给只能接受非 const 对象的函数。

  • 添加 const 属性:使用 const_cast 将非 const 对象转换为 const 对象,通常用于将非 const 对象传递给只能接受 const 对象的函数。
    示例:

移除 const 属性的示例:
#include <iostream>// 打印非const整型值的函数
void printNonConst(int* x) {*x = 20; // 修改非const整型值std::cout << "Modified value: " << *x << std::endl;
}int main() {const int i = 10; // 定义const整型值// 使用const_cast移除const属性printNonConst(const_cast<int*>(&i));return 0;
}

在这个例子中,printNonConst函数接受一个非constint指针,并修改该值。我们在main函数中定义了一个const整型变量i,然后使用const_cast将其const属性移除,以便将其传递给printNonConst函数进行修改。

添加 const 属性的示例:
#include <iostream>// 打印const整型值的函数
void printConst(const int* x) {std::cout << "Const value: " << *x << std::endl;
}int main() {int i = 10; // 定义非const整型值// 使用const_cast添加const属性printConst(const_cast<const int*>(&i));return 0;
}

在这个例子中,printConst函数接受一个constint指针,并打印该值。我们在main函数中定义了一个非const整型变量i,然后使用const_cast添加其const属性,以便将其传递给printConst函数。

reinterpret_cast

reinterpret_cast用于转换任意类型的指针。它不会检查被转换的类型是否相关,因此需要谨慎使用。
示例:

#include <iostream>int main() {int i = 10;void* p = &i;int* ip = reinterpret_cast<int*>(p);std::cout << "reinterpret_cast: " << *ip << std::endl;return 0;
}
dynamic_cast

dynamic_cast用于在继承层次结构中进行安全的类型转换,只能用于指向多态类型的指针或引用。
示例:

#include <iostream>class Base {
public:virtual ~Base() {}
};class Derived : public Base {
public:void sayHello() {std::cout << "Hello from Derived" << std::endl;}
};int main() {Base* base = new Derived();Derived* derived = dynamic_cast<Derived*>(base);if (derived) {derived->sayHello();} else {std::cout << "dynamic_cast failed" << std::endl;}delete base;return 0;
}

3. Conversion Operators (转换运算符)

从类的对象转换为指定的基本类型或其他类类型
类可以定义成员函数operator type(),实现对象到其他类型的转换。
用户定义的转换通过构造函数和转换运算符实现,允许将类对象转换为内置类型或其他类类型。
示例:

#include <iostream>class Integer {int value;
public:Integer(int v) : value(v) {}operator int() const {return value;}
};int main() {Integer integer(42);int i = integer; // 自动调用转换运算符std::cout << "Conversion Operator: " << i << std::endl;return 0;
}

4. Explicit Conversion Operators (显式转换运算符)

类似于转换运算符,但加上了explicit关键字,防止了隐式转换。这通常用于只有一个参数的转换运算符,以避免意外的类型转换
通过explicit关键字,防止隐式转换。
示例:

#include <iostream>class Integer {int value;
public:Integer(int v) : value(v) {}explicit operator int() const {return value;}
};int main() {Integer integer(42);// int i = integer; // 这行会编译错误,因为转换运算符是显式的int i = static_cast<int>(integer); // 需要显式转换std::cout << "Explicit Conversion Operator: " << i << std::endl;return 0;
}

5. 模板特化(Template Specialization)

模板特化允许为特定类型提供定制的实现,通常用于为特定类型定制转换逻辑。
示例:

#include <iostream>template<typename T>
class Converter {
public:static void convert(const T& value) {std::cout << "Generic conversion: " << value << std::endl;}
};// 对int类型进行特化
template<>
class Converter<int> {
public:static void convert(const int& value) {std::cout << "Specialized conversion for int: " << value << std::endl;}
};int main() {Converter<double>::convert(3.14); // 使用泛型转换Converter<int>::convert(42); // 使用特化转换return 0;
}

输出

Generic conversion: 3.14
Specialized conversion for int: 42

在这个例子中,定义了一个模板类Converter,并对int类型进行了特化,以提供定制的转换逻辑。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • opencv - py_calib3d - py_calibration 相机校准
  • git是什么?git和svn的区别。git的一些命令
  • 杰发科技Bootloader(2)—— 基于7840的Keil配置地址
  • Redis的五种数据类型与命令
  • 【教程】Node.js+Apache 部署网页全过程(非常详细!)
  • Knowledge Editing for Large Language Models: A Survey
  • 通信原理-思科实验三:无线局域网实验
  • 【使用 Pytest 记录日志文件并确保测试用例正常执行】
  • python实现盲反卷积算法
  • 2024最新网络安全自学路线,内容涵盖3-5年技能提升
  • Ubuntu 22.04.4 LTS (linux) GoAccess 分析 Nginx 日志
  • 如何学习自动驾驶仿真与算法优化 前后端开发
  • 深入理解Prompt工程
  • GO集成方式、Java文字识别接口集成方法
  • Odoo 17 仪表盘开发指南:打造高效的数据可视化中心
  • co模块的前端实现
  • Docker入门(二) - Dockerfile
  • github指令
  • Java深入 - 深入理解Java集合
  • Laravel 实践之路: 数据库迁移与数据填充
  • spring cloud gateway 源码解析(4)跨域问题处理
  • vue-router 实现分析
  • 那些被忽略的 JavaScript 数组方法细节
  • 强力优化Rancher k8s中国区的使用体验
  • 阿里云移动端播放器高级功能介绍
  • ​​​【收录 Hello 算法】9.4 小结
  • #565. 查找之大编号
  • #pragma 指令
  • #Ubuntu(修改root信息)
  • #Z0458. 树的中心2
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (1)bark-ml
  • (2)空速传感器
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (一)、python程序--模拟电脑鼠走迷宫
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转)http协议
  • (自用)网络编程
  • .net 重复调用webservice_Java RMI 远程调用详解,优劣势说明
  • .NET中GET与SET的用法
  • /3GB和/USERVA开关
  • [2019/05/17]解决springboot测试List接口时JSON传参异常
  • [ABC275A] Find Takahashi 题解
  • [AHOI2009]中国象棋 DP,递推,组合数
  • [android] 练习PopupWindow实现对话框
  • [android] 请求码和结果码的作用
  • [C#]C# winform实现imagecaption图像生成描述图文描述生成
  • [CSS] 点击事件触发的动画
  • [Debugger]调试Arm设备
  • [Eclipse] 详细设置护眼背景色和字体颜色并导出
  • [github全教程]github版本控制最全教学------- 大厂找工作面试必备!
  • [Java] 什么是IoC?什么是DI?它们的区别是什么?
  • [JavaScript]_[初级]_[关于forof或者for...of循环语句的用法]