c++ 中const关键字定义属性(Visual Studio又在给我们添麻烦啦)
发布日期:2021-10-07 04:43:15 浏览次数:13 分类:技术文章

本文共 1620 字,大约阅读时间需要 5 分钟。

在c++中const关键字是一个常用的点,关于const关键字的介绍网上也是比比皆是,今天写代码过程中发现一个问题在网络中没有找到,所以记载一哈。

问题发现

在c++中有四种类型转换的方式,分别是static_cast、dynamic_cast、const_cast、reinterpret_cast,关于各种转换方式的区别,可以查看别的博客,我们今天关注的是const_cast转换方式。const_cast转换方式的功能是将对象的const属性去除,下面看代码。

#include
using namespace std;int main() { const int a = 0;//定义一个常量整形 int & r = const_cast
(a);//通过const_cast去除const属性 r++;//将r自增1 cout << a << endl;//输出0 cout << r << endl;//输出1 return 0;}

这个程序的输出结果已经注释在代码中了,代码中确实使用了const_cast进行去除了,为什么打印的结果还是0呢,难道是const_cast的功能失效了?下面看另一段代码。

#include
using namespace std;int main() { int i; cin >> i;//这里我们随意输入,输入一个0吧 const int a = i; int & r = const_cast
(a); r++; cout << a << endl;//输出1 return 0;}

经过这段代码可以看出来,const_cast确实将a的const属性去除了,那为何第一段代码出问题了呢?为何打印r的时候又正确了呢?

问题分析

分析两段代码,唯一的区别就是对a的赋值,第一段代码中,直接使用的是一个常量,第二段代码中则是通过变量i,运行的时候输入的,所以可能是这个原因造成的。在以const int a=0的方式进行定义的时候,编译器会在编译阶段,将a直接替换成0,所有的出现a的地方都变成了0,那么输出a的时候就直接语句变成了输出0,所以在去const之后,即使正确的修改了a的值,输出语句也无法正常执行。但是第二个是在运行时期确定的,a的定义位置也是栈中,所以在使用输出语句的时候,输出语句还是指向a的地址的,所以可以正确输出。所以问题的关键应该不是const_cast没有起作用,而是编译器给我们做了一个坏事。

分析验证

查看第一段代码中的a的地址和b的地址:

int main() {    /*int i;    cin >> i;*/    const int a = 0;    int & r = const_cast
(a); r++; cout << &a << endl;//00AFF7D4 cout << &r << endl;//00AFF7D4 return 0;}

说明这里的r并不是副本,而是真正的a,那么为何会输出0呢?再看调试时的状态,如下图:

这里写图片描述
下图我们可以看出,此时a的值确实已经变成了1,但是输出的确实为0,真是一个匪夷所思的操作呀。 看来编译器翻译是有问题的,我们来查看下汇编代码,如下图:
这里写图片描述
如图所示,问题的源头显示出来了!在地址为00A51EE1处,代码为push 0,此处是为cout赋予参数的,但是居然直接是0,而没有引用a这个变量,看来编译器把const不当变量呀。
现在问题解决了,不是const_cast的问题,而是vs在编译阶段做的替换的问题,这应该也是vs上的一个bug吧,希望大家coding的时候可以注意一下。

转载地址:https://blog.csdn.net/meanong/article/details/81355106 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:学习高手的代码风格之(一)---strlen反汇编分析
下一篇:windows平台中让函数在main函数之前执行的方法

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月19日 13时36分59秒