谈谈int*转const int* &的问题

最近看代码遇到个指针的const引用的问题,指针真的是让人又爱又恨呐,太微妙了。指针和引用的再深入,记录分享下

情况是这样的

我是在这里遇到的,简化代码如下:

template <class T>
void show1(const T & i)
{
    // i = (T)0x555555;   编译报错
    // *i = 1314;   编译通过,效果正常
    cout << (void*)i << endl;
}
void show2(const int* & i)
{
    cout << (void*)i << endl;
}
int nTemp = 2019;
int * ptrInt = &nTemp;
show1(ptrInt);           //可以通过编译,而且我已验证确实是真正的const引用
show2(ptrInt);       //不能通过编译。cannot bind non-const lvalue reference of type 'const int*&' to an rvalue of type 'const int*'
/

简单来说就是这么个情况:

int nTemp = 2019;
int *ptrInt = &nTemp;
const *ptrInt2 = &nTemp;
const int* &refptrInt1 = ptrInt;   //1.这种用法会报错。你思考过吗,你觉得呢?

//下面是验证代码
const int* &refptrInt2 = ptrInt2;   //2.这个引用是const的吗
// *refptrInt2 = 999;      //error: assignment of read-only location '* refptrInt2'
refptrInt2 = (int*)0x1234;

int* const &refptrInt2 = ptrInt;    //3.其实,这个才是ptrInt的真正const引用。
*refptrInt2 = 999;
// refptrInt2 = (int*)0x1234;    //error: assignment of read-only reference 'refptrInt2' 

阐述一下

谈谈我的理解吧!
问题的关键还是在于const限定符修饰指针类型数据的神奇之处。也就是const*之前之后的差异。

像如下这种单个token的类型说明符(比如int)很好理解,

int a = 0;
const int &crefa = a;(等同表示:int const &crefa = a;)  

crefa标识符为const int引用类型,不能修改其标识符对应存储的值。

而像对于指针这种需要两个token的类型说明符(int*)的情况,就有时让人绕不过弯了。

int *pa = &a;

(int*)类型pa标识符对应的const引用应该是哪种呢?首先,其const引用,表示的效果应该也是其标识符对应存储的值不能修改。指针还不就是一个存储的值为地址的特殊变量。然后,了解了const在*前后的差异就该明白了。

int nage = 18;
const int *pt = &nage;    //a pointer to const int,不能修改指针存储的地址指向的变量的值。 解引用后内容是常量。
int* const pu = &nage;    //a const pointer to int,不能修改指针存储的地址,即改变不了指向的位置了。指针变量内容是常量。

其对应的const引用,应该这样表达:

int* const &crefpa = pa;   //和验证代码里的是一致的,这才是真正的指针的const引用想表达的意思

而不该是const int* &crefpa = pa; 其对应的该是const int* pa = &a;

而且,引用设计上还不就是指针,其实就是类似如下的伪装表示:

int a;
int & refint = a;   
int * const pint = &a;

其const就该是

int [const] &refint = a;  
int [const] * const pint = &a;  
//[const] int * const pint = &a; 同上

当为单个token,int时,其和const交换不影响编译器语义,如果是双token,int*时,不影响才怪呢。

int* [const] &refint = a;  
int* [const] * const pint = &a;  
//[const] int* * const pint = &a;  还同上吗?

顺便说下,我遇到的情况,更验证了我的说辞。
而且,模板函数实例化看来是做了特殊处理了。类型参数T,可不是简单的替换啊,是一个独立的部分了。 比如当T == int *时,const T & 和T const&,是完全一样的,不影响语义,都是int* const &可以放心用其表示const引用。

template < class T >
void show1(const T & i)
{
// i = (T)0x555555; 编译报错
// *i = 1314; 编译通过,效果正常
cout << (void*)i << endl;
}


myAvatar

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值