谁改了我的const引用?

注:转载必须注明出处,绝对原创

曾经在工作中遇到一个问题:
两个指针指向同一块堆地址,如果一个指针释放了,那么另一个指针怎么知道呢?
1:在debug中,可以通过指针释放之后那段内存的值是多少可以初步推断,一般有0xcccccccc,
或者0x000000,或者0xffffff。但是这个根据编译器不同而不同,一般程序的发布版本都会用release
版本。
2:在release中,释放的堆内存有优化,值是个随机的数,那就没办法判断了。
最开始我想到了引用,我想既然有指针变量的引用,那么是不是一个指针释放了,那么就可以
通过引用知道呢?(如果你对引用了解的足够本质,你绝不会有这种想法)

以前我写过一个程序:
程序如下:

#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int *& fun() { const int *p=new int[100]; return p; } int main() { const int *const &p1 = fun(); cout<<"before p1 :"<<hex<<p1<<endl; cout<<"after p1 :"<<hex<<p1<<endl; getchar(); return 0; }

结果如下:

before p1 :003D5218 after p1 :10572AC8

两次同样的连续的,对同一个变量的输出语句,竟然结果不一样!细心的同学会发现,
用vs或者g++在编译的时候会有一个警告:warning C4172: returning address of local variable or
 temporary
或者:warning: reference to local variable 'p' returned
没错,我们fun函数返回的变量是个局部变量,不要认为没什么关系
1:首先,有警告就是编程不规范,除非你知道你做的绝对没错,可是这里,你保证不了
2:不要认为“可是我的堆没释放,返回也可以接着用啊”,那么你怎么解释两次的输出结果
不一样呢?

这也就涉及到引用的本质是什么了,最开始学引用,看书本的介绍,总感觉引用特别神奇,
以为编译器做 了什么神奇的操作(使引用不成为一个对象,不占内存空间,只是别人的一
个别名,神一般的感觉!), 通过自己写程序,看汇编,才发现,原来他的实现方式就是
指针,其实他占内存,除了使用方法有点不同, 就是一个常量指针的功能(一对一),
引用的本质更像指针(一对多)的一个子集。
引用多一个&可以说就是代表多一级指针,只是使用方式按照没有&的方式使用,
编译器做了(*解引用操作)。 上面的程序,可以很方便的改成二级指针。结果类似。

其实是编程不规范和对引用的本质了解的不够的原因,你可以把fun里面的p改成static,
就好了
那么,输出结果不一样的原因是什么:看下图


引用了(二级指针指向了)一个局部变量(在栈中),那么,回到fun调用完之后,主函数的
cout也会有入栈,这样其实你们看看汇编代码就知道,栈中的那个引用值被cout的入栈覆盖了。
 
类似的,改成二级指针供参考

#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int ** fun() { const int *p=new int[100]; return &p; } int main() { const int **const p1 = fun(); cout<<"before p1 :"<<hex<<*p1<<endl; cout<<"after p1 :"<<hex<<*p1<<endl; getchar(); return 0; }

结果为:

before p1 :002A5218 after p1 :10572AC8

那么回到题目,你就知道,所谓的常量指针,所谓的(常量)对const引用,都不过是‘不能通过他们

自己改变值’罢了,其他人是可以改他们‘自认为’的常量的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值