首页 > 编程语言 >警惕 C++ 中的隐式类型转换

警惕 C++ 中的隐式类型转换

时间:2023-10-16 14:32:47浏览次数:35  
标签:类型转换 BigBuffer topomel C++ 编译器 移步 com 隐式 构造函数


今天文章的主题灵感来自客户的一个问题:

我在研究一个代码中的栈溢出问题。为了减小栈帧的大小,我尽可能多地删除了局部变量,但仍有很多栈空间无法解释。除了局部变量、参数、保存的寄存器和返回地址之外,栈上还有什么其他的东西呢?

我的回答是,嗯,还有结构化(SEH)的异常处理信息,但这通常不会占用太多栈空间,因此不会成为”大量”神秘栈使用的来源。

我的猜测是,代码正在生成大量大型 C++ 临时对象。请考虑以下程序片段:

警惕 C++ 中的隐式类型转换_构造函数

>> 请移步至 topomel.com 以查看图片 <<

有人会问了:”这段代码是如何编译的?函数Foo想要一个BigBuffer,而不是一个整数!” 然而编译它确实如此。

这是因为编译器使用 BigBuffer 构造函数作为转换器。换句话说,编译器插入了以下临时变量:

>> 请移步至 topomel.com 以查看图片 <<

警惕 C++ 中的隐式类型转换_windows_02

这样做是因为,只接受一个参数的构造函数有两个目的:它可以用作传统的构造函数(正如我们在 BigBuffer temp(3) 中看到的那样),或者它可以用来提供从参数类型到构造类型的隐式转换。在本例中,BigBuffer(int) 构造函数被用作从 int 到 BigBuffer 的转换。

若要防止这种情况发生,请使用 explicit 关键字:

>> 请移步至 topomel.com 以查看图片 <<

警惕 C++ 中的隐式类型转换_系统设计_03

通过此更改, 对 Foo(3) 的调用会引发编译器错误:

>> 请移步至 topomel.com 以查看图片 <<

警惕 C++ 中的隐式类型转换_软件开发_04

总结

通过今天的文章,我终于理解了在何种情况下需要在构造函数上加 explicit 。
你呢?

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《Beware the C++ implicit conversion》

警惕 C++ 中的隐式类型转换_构造函数_05

警惕 C++ 中的隐式类型转换_软件开发_06

 

标签:类型转换,BigBuffer,topomel,C++,编译器,移步,com,隐式,构造函数
From: https://blog.51cto.com/u_15805075/7883510

相关文章

  • .NET 一些常用的类型转换扩展
    ///<summary>///转换扩展类///</summary>publicstaticpartialclassExtensions{#region转换为long///<summary>///将object转换为long,若转换失败,则返回0。不抛出异常。///</summary>///&l......
  • Qt/C++编写物联网组件/支持modbus/rtu/tcp/udp/websocket/mqtt/多线程采集
    一、功能特点支持多种协议,包括Modbus_Rtu_Com/Modbus_Rtu_Tcp/Modbus_Rtu_Udp/Modbus_Rtu_Web/Modbus_Tcp/Modbus_Udp/Modbus_Web等,其中web指websocket。支持多种采集通讯方式,包括串口和网络等,可自由拓展其他方式。自定义采集间隔(精确到毫秒)和超时次数,超时后自动将离线的文件......
  • UE4 C++关联蓝图界面(仅显示)
    使用的自带第三人称c++模板,UE4.27实现教程参考:UE5虚幻引擎C++【第六期】实现UMG控件_哔哩哔哩_bilibili1.创建一个蓝图界面控件,设置好布局2.找到项目代码xx(项目名称).build.cs文件1)添加UMG及后续部分,使得可以调用蓝图模块相关内容PublicDependencyModuleNames.AddRange(news......
  • VSCode 配置C++环境
    MinGW肯定要装的。复制json这篇就够了,但终端会闪掉:VsCode安装和配置c/c++环境(超完整,小白专用)_vscodec++环境-CSDN博客这篇文章配终端:VSCode中C/CPP的完美配置(完成环境搭建、解决终端自动闪退、解决无法调试)-知乎(zhihu.com)......
  • C++学习笔记Day1
    有关const的一些事1.const对象必须初始化,因为const对象一旦创建,其值不能再被改变。2.const对象是常量,因此可以赋予其字面值。3.普通变量默认支持多文件下共享,而const默认不支持,需要在定义和声明是都加上关键字extern才能在多个文件中使用。4.所谓“常量引用”指的是“对const......
  • C++基础认识(新手村)day2
    引用的使用场景1.引用作为函数参数//1.引用作为函数参数voidfun1(int&a,int&b){ intsum=a+b; cout<<"sum="<<sum<<endl;}voidtest1(){ inta=10; intb=20; fun1(a,b);}2.引用作为函数的返回值//2.引用作为函数的返回值int&fun2(){ intb......
  • C++原始数据类型
    不同数据类型之间唯一的区别就是大小,根据分配内存来决定使用哪种数据类型来创建变量几种基础数据类型int(integar)该数据类型允许我们在给定的范围内存储一个整数传统上int是四字节大小的数据类型,实际大小根据所选择编译器的不同而有所不同char一个字节的数据类型传统上用......
  • C++ 引用本质
    @TOC前言C++引用及其本质在C++中,引用是一项强大而灵活的特性,允许程序员通过引用访问和修改变量的值。本文将深入探讨C++引用的本质、用法、优势以及与指针的比较等方面。1.引用的基本概念引用是C++中的一个别名,用于标识已经存在的对象或值。引用通过在变量声明时使用&符号来创建,......
  • C++ 引用本质
    @TOC前言C++引用及其本质在C++中,引用是一项强大而灵活的特性,允许程序员通过引用访问和修改变量的值。本文将深入探讨C++引用的本质、用法、优势以及与指针的比较等方面。1.引用的基本概念引用是C++中的一个别名,用于标识已经存在的对象或值。引用通过在变量声明时使用&符号来创建,......
  • C++类内存布局与虚继承
    类的内存布局本文参考浅析C++类的内存布局,做了一些修改和补充1.无继承的情况为了得到类的内存布局,先设置一下输入/d1reportAllClassLayout,结果会在输出窗口打印出。最后会打印很多类,基本上最后就是自己的类的布局,也可以指定类。如果写上/d1reportSingleClassLayoutXXX(X......