首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

c++ const 引用赋值异常

2013-07-08 
c++ const 引用赋值错误代码如下:int ival 1024int* pival &ivalint*& sdf pival //正确const in

c++ const 引用赋值错误
代码如下:


int ival = 1024;
int* pival = &ival;
int*& sdf = pival; //正确
const int*& pi_ref = pival;//错误,为什么
const int* const& pi_ref = pival;//正确

错误信息:

error: invalid initialization of reference of type 'const int*&' from expression of type 'int*'


请问为什么错误呢,我在codeblocks下用gcc编译的。 C++
[解决办法]
T * 是一个 T const *, T & 是一个 T const &
但是T ** 不是一个 T const **,T * &也不是一个T const * &
T ** 是一个T * const *,T * &是一个T * const &

上面说的“是一个”意思就是可以隐式转换。
第一个,不用说了,大家都明白,non-const指针/引用可以转换为const指针引用
第二个,很久以前我们就讨论过:

int * a;
int const * b;
int const ** c = &a;//假如这一步允许的话
*c = b; //现在a就等于b,我们成功地把一个int const *赋值给了一个int**,没有任何另人警惕的强制类型转换。
上面两个赋值,后面那个肯定不能禁止 ,否则会让指针失去存在意义,所以第一个赋值被禁止,T **不允许隐式转换为T const **


第三个(我列出来的,不是楼主的代码):
typedef P = T*;
T**就是P*, T*const *就是P const *,又回到了第一条。

最后再看楼主的最后一行代码:
const int* const& pi_ref = pival;//正确 

pival类型是int*,pi_ref类型比较复杂,我们可以定义一下:
typedef int* PInt;
typedef int const * PCInt;
PInt可以 隐式转换为PCInt;
pi_ref是PCInt const &
pival是PInt,可以隐式转换为PCInt。
现在清楚了,为了支持函数参数中用const reference代替值拷贝,C++允许 对象A隐式转换为B的传给B const &类型。这里有一个隐式类型转换,由pival转换为PCInt然后赋值给PCInt const &类型的pi_ref

注意,const是左结合 的它修饰的是它左边的类型,当它在最左时才修饰右边,所以const int与int const是等价的。我一般为了清晰,都写后一种。

此外,我现在的系统很慢,输入法的响应远跟不上我输入的速度,所以会有多空格 、少字、少标点的情况 请大家谅解。



[解决办法]
楼上说的都有点问题,其实楼主发生的问题与大家熟知的const int **与int**之间的转换问题并不是同一类问题,两者是不同的情况。

const int*& pi_ref = pival;不行是因为从int*到const int*的转换需要产生一个临时对象,但pi_ref属于非const对象的引用,大家都知道非const对象的左值引用是不能用右值进行初始化的,这是常识。因此上述语句不能通过编译,pi_ref引用的类型加上const后,才能引用右值,所以const int* const& pi_ref = pival;才是正确的。



楼主提出的问题与下述现象才是同一类问题:


int & r0 = 20.0;  //失败
const int & r1 = 20.0; //成功



[解决办法]
看看这个
[解决办法]
引用:
Quote: 引用:

楼上说的都有点问题,其实楼主发生的问题与大家熟知的const int **与int**之间的转换问题并不是同一类问题,两者是不同的情况。

const int*& pi_ref = pival;不行是因为从int*到const int*的转换需要产生一个临时对象,但pi_ref属于非const对象的引用,大家都知道非const对象的左值引用是不能用右值进行初始化的,这是常识。因此上述语句不能通过编译,pi_ref引用的类型加上const后,才能引用右值,所以const int* const& pi_ref = pival;才是正确的。

楼主提出的问题与下述现象才是同一类问题:


int & r0 = 20.0;  //失败
const int & r1 = 20.0; //成功

1.从int*到const int*的转换需要产生一个临时对象,
这句话是不是说pi_ref 引用的不是pival,而是pival隐式转化为const int*类型后的临时对象?像4楼plainsong说的那样?
2.pi_ref属于非const对象的引用,
这句话不是很理解,const int*& pi_ref = pival;
pi_ref引用的是一个指向整型常量的指针,你说pi_ref属于非const对象的引用是指它引用的指针不是常量指针,虽然这个指针指向的是一个整型常量(const int),是这个意思吧?
加上一个const后变成const int* const& pi_ref = pival;
这句话的意思是pi_ref引用的是一个指针常量,这个指针不可以修改,然后这个指针指向的是一个整型常量。是这样吗?这个新加的const是说引用是const的还是指针是const的呢?
3.pi_ref引用的类型加上const后,才能引用右值
这里pival不是右值,你说的右值是不是我第一个问题里面的临时变量,如果是这样,c++的临时变量是右值,是这样吗
多谢了


1、是的。
2、是的,新加的const修饰的是指针,不是引用,const引用是不存在的,因为引用本身是不可修改的。此外,虽然常量的说法不正确,但不影响你对此问题的理解。
3、是的。注意你提到的临时变量是错误的,不存在临时变量,因为变量一定是有名字的,正确的术语叫临时对象。

热点排行