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

跟我学c++中级篇——隐式转换的意义

一、隐式转换

以前分析过C++中的数据类型的转换,也顺带介绍过隐式转换。本文重点分析一下,为什么C/C++中需要存在隐式转换这一种数据类型的转换方式。隐式转换,就是由编译器自动处理数据类型的转换而不需要开发者进行干预的过程。

二、隐式转换种类

隐式转换主要有以下几种情况:
1、基础类型的隐式转换
这种转换非常常见,比如在传递参数时,向一个double类型的参数传递一个int类型的基础类型值,则编译器会自动的进行隐式的转换。另外,编译器默认把非显式声明的数据类型默认为int类型,也可以认为是一种隐式转换。

void getData(double c){...}
int main(){int d = 0;getData(d);return d;
}

2、类对象的隐式转换
在C++中类对象的隐式转换比较复杂,但通晓其原理后就会比较清楚了,主要有:
a)单参数构造函数的隐式转换
b)通过重载运算符实现隐式转换(包括在新标准中的operator转换,可参看前面的“c++11的类型转换函数”)
3)父子类对象间的隐式转换

class Base { };
class Derived : public Base { };void controleType(Base b) { }  int main() {Derived d;controleType(d);  return 0;
}

3、wrapper的隐式转换
在标准库中提供了大量的这种转换,如万能引用和在模板中用到的std::reference_wrapper等。

三、控制隐式转换

一般来说,对基础类型的隐式转换出现问题的概率不大,但正是因为概率不大,出现问题后反而不容易想到它。比如前面提到的有符号和无符号的转换,导致的判断异常。所以,正常编程的情况下,能不使用隐式转换就尽量避免使用隐式类型转换。在C++中为了控制隐式转换,提供了几种方法:
1、使用几种cast
如常见的static_cast,const_cast等,它们提供了基础的安全保障,建议在做数据类型转换时,使用它们。
2、类中的显示explicit
在控制类对象的隐式转换中,显示的使用explicit关键字,防止单参数构造函数对象的隐式转换。并限制对一些特殊符号的重载动作或显示的提供重载的注释等文档提示。在涉及到继承的隐匿转换时,要做好父子类的权限控制等操作,防止出现一些简单的基础问题。
3、模板的隐式转换控制
模板中的隐式转换控制建议使用SFINAE技术或更高版本中的概念(Concpts)等来实现

四、实际的例子

控制隐式转换的例子很多,下面看几个基础的例子:

double d = 3.14;
int i = static_cast<int>(d);  class Base { virtual void dummy() {} };
class Derived : public Base {};Base* basePtr = new Derived();
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);const int c = 42;
int* modifiable = const_cast<int*>(&c);  
//explicit
class Demo {
public:explicit Demo(int d) : data(d) {}  // 显式构造void print() const {std::cout<<"data is:"<<data<<std::endl;}
private:int data;
};void display(const Demo& dm) {dm.print();
}int main() {// display(7);          // 错误display(Demo(7));  // 正确return 0;
}

SFINAE和Concepts的例子在前面写了很多,这里不再重复,有兴趣的可以搜索一下前面的相关文章即可,或直接在网上查找相关的资料。

五、隐匿类型转换的意义

通过上面的分析,初步明白了隐式转换的内容,那么为什么会存在这种情况呢?其实就是为了方便简单。正如在实际生活中,把一根木杆截短(而不是寻找一个等长的木杆)和把一个豆子放进碗里(而不是为了一个碗而装装一整碗的豆子)是非常常见的。这样做既简单又方便,更重要的是,它比寻找一个合适的匹配更节省成本,看似牺牲了一些成本,但在另外一方面节省了更多的成本,尤其是时间成本。
综上所知,隐式转换的存在的根本原因就是取得整体成本上的优势并让开发在这个方面变得简单无需程序员直接处理。当然,世界上没有免费的午餐,这样做自然就代入了隐式的风险(这在前面已经分析过了),但只要能够控制好这种风险,隐式转换就有存在的意义。

六、总结

隐式转换是不安全的,但又是简单省事的。所以,最好的应用方法是尽可能的在安全的前提下减少使用这种方式。标准的发展也是如此,尽量将隐式转换控制在可控的范围内并逐渐减少这种应用。
最终还是那句话,可控的选择合适的应用场景,就不会有问题。

http://www.xdnf.cn/news/10277.html

相关文章:

  • PostgreSQL的扩展 dblink
  • MySQL--day10--数据处理之增删改
  • 【Java实战】低侵入的线程池值传递
  • Jinja2 模板继承机制
  • 【Linux】mmap文件内存映射
  • LeetCode[257]二叉树的所有路径
  • 4.2.4 Spark SQL 数据写入模式
  • 67.实现AI流式回答的后端实现(2)
  • Vue-Router简版手写实现
  • 2025年5月个人工作生活总结
  • lstm 长短期记忆 视频截图 kaggle示例
  • Rock9.x(Linux)安装Redis7
  • 寒假学习笔记【匠心制作,图文并茂】——1.20拓扑、强连通分量、缩点
  • CppCon 2014 学习: The Implementation of Value Types
  • Compose原理 - 整体架构与主流程
  • JDK21深度解密 Day 8:Spring Boot 3与虚拟线程整合
  • 【清晰教程】查看和修改Git配置情况
  • SCSS 全面深度解析
  • neo4j 5.19.0安装、apoc csv导入导出 及相关问题处理
  • Windows最快速打开各项系统设置大全
  • RAID磁盘阵列配置
  • 鸿蒙编译ffmpeg库
  • M4Pro安装ELK(ElasticSearch+LogStash+Kibana)踩坑记录
  • 性能优化 - 理论篇:性能优化的七类技术手段
  • SMT贴片机工艺优化与效率提升策略
  • WEB3——为什么做NFT铸造平台?
  • 配置远程无密登陆ubuntu服务器时无法连接问题排查
  • 系统是win11+两个ubuntu,ubuntu20.04和ubuntu22.04,想删除ubuntu20.04且不用保留数据
  • 【图像处理入门】3. 几何变换基础:从平移旋转到插值魔法
  • day15 leetcode-hot100-29(链表8)