> 文章列表 > C++11 左值、右值、纯右值、将亡值

C++11 左值、右值、纯右值、将亡值

C++11 左值、右值、纯右值、将亡值

1.类型与值类别:

        C++表达式:类型和值类别。每个表达式只属于三种基本值类别中的一种:左值、右值、将亡值,每个值类别都与某种引用类型对应。

1.1左值

能够用&取地址的表达式是左值表达式

int main ()
{int a=10;const int b=20;int *p=&a;const int*cp=&b;
}

1.2纯右值

凡是不能够取地址,本身就是赤裸裸的、纯粹的字面值是纯右值

字面常量10,12.23,nullptr;不可取地址,我们称之为右值,也成为纯右值。

总结:所有的具名变量或对象都是左值,而右值不具名。

1.3将亡值

描述:在表达式的运行或计算过程中所产生的临时量或临时对象,称之将亡值;临时量有可能是字面值,也可能是一个不具名的对象。

内置类型:

int func()
{int x=10;return x;
}
int main ()
{int a=10;int b=10;i=a+b;++i;i++;&a;a=func();//函数返回时构造临时量,是将亡值,纯右值return 0;
}

        算术表达式(a+b、a&b、a<<b)、逻辑表达式(a&&b、a||b、~a)、比较表达式(a==b、a>=b、a<b、a!=b)、取地址表达式(&a)等,计算结果相当于字面值,(数据实际存储在CPU的数据寄存器中),所以是将亡值,此将亡值不可写·,由于运行结果是字面量,所以是纯右值。

        对i加1后再赋值给i,最后返回的结果就是i,所以,++i的结果具名的,名字就是i,所以是左值。

        而对于i++来说,是先对i进行一次拷贝(计算过程中所产生的临时量),将得到的副本作为返回结果,然后再对i+1,由于i++的结果是对i+1前的一份拷贝,它不是具名,所以是将亡值,此将亡值不可写,所以也是右值。由于运行结果是字面值,所以是纯右值。

类类型(程序员自己设计的类型)

类类型:程序员自己设计的类型,通过概念设计类型,概念来自实体

class Int
{int _value;
public:Int(int x=0):_value(x) { cout<<"Create Int:"<<_value<<endl;}Int(const Int& it):_value(it._value){cout<<"Copy Create Int:"<<this<<endl;}Int&operator=(const Int&it){if (this==&it)return *this;_value=it._value;cout<<this<<"="<<&it<<endl;return *this;}~Int(){cout<<"Destroy Int:"<<_value<<endl;}void SetValue(int x){_value=x;}int GetValue()const {return _value;}void ShowValue()const{cout<<_value<<endl;}
};
int main ()
{Int a(1);const Int b(20);Int(2);//不具名对象,为右值a.ShowValue();Int(3).ShowValue();Int*ip=&Int(5);//不具名对象,是将亡值,不可以取地址,为右值return 0;
}

对象a是左值,可以取地址&a;

Int(2)程序运行过程中所产生了不具名对象,将亡值。不可以取地址&Int(2)错误

内置类型的将亡值,只能读不能改,我们自己设计的类型的将亡值可以改。

将亡值生存期在表达式调动过程中存在。

对于类里面的成员函数 核心:this指针。

函数被调用时被分配一个栈帧(一块一块分配的栈)

函数不要把局部变量以引用和指针返回,会产生失效指针

这个变量或对象不受函数生存周期的影响(函数结束不释放我的空间)例如:全局变量、静态变量、变量以引用进以引用出

空间只能去申请,不能被创造

构造函数的作用:1.创建对象  2.对创建的对象初始化  3.隐士类型转换

任何对象只能被系统构造一次,在对象的生存空间中构造函数只存在一次也仅存在一次 

ststic 和全局变量不能用const修饰,因为没有this指针