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指针