为何非常量引用类型不可以赋值为临时变量?
我是个c++菜鸟,不过发现c++比c有趣,很多地方可以研究。
今天编译了一个小程序
int &r = 12;
程序编译通不过,“error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’” 大概的意思是非常量int引用不可以用int右值表达式初始化。
如果我写成
int &r = int(12)也不行。
但是我换成这样的后就可以了通过编译:
int &r = new int(12)
请问大家
1. int(12)和12有区别吗?int(12)返回的是int object还是int变量,如果是int object,这个object有什么特殊?有析构函数吗?有其他的成员变量吗?
2. 为何int &r = * new int(12)可以?
[解决办法]
>>1. int(12)和12有区别吗?
在这里木有。整形常量的类型根据其值从 2.14.2 table-6 确定其类型,12 的话属于 int.
>>int(12)返回的是int object还是int变量,如果是int object,这个object有什么特殊?
int(12) 是右值,这是绑定失败的根本原因。
>>有析构函数吗?
内建类型没有,类对象才有构造函数呢。
>>有其他的成员变量吗?
没有。
>>2. 为何int &r = * new int(12)可以?
因为 * 操作符返回左值,所以绑定成功。
[解决办法]
int x=10;
00352B91 mov dword ptr [ebp-44h],0Ah
int *p,&r = x;
00352B98 lea eax,[ebp-44h]
00352B9B mov dword ptr [ebp-5Ch],eax
p = &x;
00352B9E lea eax,[ebp-44h]
00352BA1 mov dword ptr [ebp-50h],eax
r = 20;
00352BA4 mov eax,dword ptr [ebp-5Ch]
00352BA7 mov dword ptr [eax],14h
建议学学汇编吧,只需要一点点汇编知识,就能看懂上边的代码。
只要懂一些汇编,你会非常非常容易理解C++中的各种东西。
[解决办法]
12 和 int(12) 功能一样,但是 integer-literal 和 int(integer-literal) 功能不一样,所以这两种模式的功能不重复。举个例子,假设 123456789 是系统上 int 类型能表示的最大值,那么 1234567890 和 int(1234567890) 就不一样了,前者可能会成为 long int 类型,而后者一定是 int 类型,而且由于这里数据过大的问题,会发生截断。
[解决办法]
主楼的问题看汇编没用,因为是编译错误,压根就没有生成对应的汇编,没的可看。
[解决办法]
让我么先从引用reference的定义说起吧:
A reference defines an alternative name for an object. A reference type “refers to”
another type.
引用是为一个对象object定义的别名,引用type 是“引用” 另外一个类型。
在c++中,表达式 int &r = 12 中,12称作 literal,首先12不是一个对象,不是一个对象,就无法引用。再说也不知到12这个literral是什么类型type,int么,long int么,short么 等等,根本无法确定其type,也就更无法引用。
[解决办法]
int& 引用类型引用的必须是左值,左值具体是啥定义我不太清楚,我理解的就是能够做左值的都可以对其进行改变,例如赋值,而右值则是不能这样。
例如:
int a;
a = 12; a是左值,这句没问题
12 = a; 12是右值,这句就有问题了。
所以 int &r = 12;是编译不过。
但const int&是可以引用右值的,所以const int& r = 12;就可以编译过。
在《effective C++》前面,大概是第20个item,用 pass-by-reference-to-const(传引用给 const)取代 pass-by-value(传值),这一节里有相关的比较详细的描述。这书很不错,建议楼主看看。
