今天文章的主题灵感来自客户的一个问题:
我在研究一个代码中的栈溢出问题 。为了减小栈帧的大小,我尽可能多地删除了局部变量,但仍有很多栈空间无法解释 。除了局部变量、参数、保存的寄存器和返回地址之外,栈上还有什么其他的东西呢?
我的回答是,嗯,还有结构化(SEH)的异常处理信息,但这通常不会占用太多栈空间,因此不会成为”大量”神秘栈使用的来源 。
我的猜测是,代码正在生成大量大型 C++ 临时对象 。请考虑以下程序片段:
![警惕 C++ 中的隐式类型转换](http://img.jiangsulong.com/230814/1H64414W-0.png)
文章插图
【警惕 C++ 中的隐式类型转换】有人会问了:”这段代码是如何编译的?函数Foo想要一个BigBuffer,而不是一个整数!” 然而编译它确实如此 。
这是因为编译器使用 BigBuffer 构造函数作为转换器 。换句话说,编译器插入了以下临时变量:
![警惕 C++ 中的隐式类型转换](http://img.jiangsulong.com/230814/1H64424C-1.png)
文章插图
这样做是因为,只接受一个参数的构造函数有两个目的:它可以用作传统的构造函数(正如我们在 BigBuffer temp(3) 中看到的那样),或者它可以用来提供从参数类型到构造类型的隐式转换 。在本例中,BigBuffer(int) 构造函数被用作从 int 到 BigBuffer 的转换 。
若要防止这种情况发生,请使用 explicit 关键字:
![警惕 C++ 中的隐式类型转换](http://img.jiangsulong.com/230814/1H6445442-2.jpg)
文章插图
通过此更改,对 Foo(3) 的调用会引发编译器错误:
![警惕 C++ 中的隐式类型转换](http://img.jiangsulong.com/230814/1H644K48-3.png)
文章插图
总结通过今天的文章,我终于理解了在何种情况下需要在构造函数上加 explicit。
你呢?
最后Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助 。
本文来自:《Beware the C++ implicit conversion》
推荐阅读
- 洪灾之后防大疫,这几类疾病要警惕!
- 警惕!电影《孤注一掷》的剧情就在你身边上演,小心套路
- 正在从icloud中下载此项目中的部分视频 正在从icloud下载信息是什么意思
- 十大不建议买的纯牛奶排行 结冷胶在牛奶中的作用
- 困境中的留学生:80%想回国就业;感觉留学不加分、想进国企;担心没竞争力
- 怎么把书本中的图片扫描成电子档 如何将书本上的图片扫描成电子版
- 学制填什么 高中的学制填什么
- 上古八大奇花传说中的花有哪些种类 上古八大奇花传说中的花有哪些
- 颜值在职场中的作用
- 高并发中的线程与线程池