(1)首先说左值和右值的定义:
变量和文字常量都有存储区,并且有相关的类型。区别在于变量是可寻址的(addressable)对于每一个变量都有两个值与其相联:
1).它的数据值,存储在某个内存地址中。有时这个值也被称为对象的右值(rvalue,读做are-value).我们也可认为右值的意思是被读取的值
(read value)。文字常量和变量都可 被用作右值。
2).它的地址值——即存储数据值的那块内存的地址。它有时被称为变量的左值(lvalue,读作ell-value)。我们也可认为左值的意思是位置值
location value文字常量不能被用作左值.
(2)
首先对于i++的实现是:
int temp;
temp = i;
i = i+1;
return temp;
而++i的实现是:
i = i+1;
return i;
所以对于我们提出来的问题已经能得到解决了:
i++=5; 是错误的是因为i++返回的是编译器自动分配的临时变量temp,而这个temp并不是你程序中定义的可寻址变量的引用 ,也就是说你不能通
过地址对它进行操作.(换句话说就是不能作为左值)
++i=5;是正确的就是因为其返回值就是i;
另外付个例子好让理解:
class mycalss
{
public:
mycalss(int myint = 6)
{
}
int getint()
{
int temp = 6;
return temp;
}
int& getmyint()
{
return myint;
}
private:
int myint;
};
int main(void)
{
mycalss a;
// a.getint() = 6;
a.getmyint() = 8;
return 0;
}
为什么说只是针对int呢,因为在类里面a++和++a都是可以作为坐值的,看下面例子:
class mycalss
{
public:
mycalss(int i = 6)
{
lint = i;
}
mycalss operator++(int)
{
//a[7][7] = 6;
mycalss oldclass = *this;
return oldclass;
}
mycalss& operator++()
{
return *this;
}
private:
int lint;
};
int main()
{
mycalss a;
a++ = 6;
++a = 6;
return 0;
}
解释: a++ 返回一个myclass对象,然后通过隐式转换把6转换为mycalss对象,然后调用复制函数把6构造出来的对象付给a
当然面对这种情况,可以选择把构造函数定义为explicit防止隐式转换。