新特性(3)---move语义

move语义

左值和右值

在说move语义之前,不得不说的是左值和右值。
通俗简单点的讲左值和右值通过是否在内存中有空间来分类。左值是在内存空间实体如(变量和函数等),而相反的没有空间的为右值如临时对象。

	int a=1;//a为左值,1为右值
	int *p = &a;//p为左值
	int f = test();//test()返回一个临时对象,为右值

再比如这样,test()返回一个全局变量是一个左值

int t;
int & test()
{
      return  t;
}

test()=5;

左值引用

顾名思义,左值引用又分为常量左值引用和非常量左值引用,区别 在于使用了const是否能改变。

int b;
int &a=b;//常量左值引用
const int &c=b;//非常量左值引用

非常量左值引用只能引用非常量左值,如

int a;//非常量左值
const int b;//常量左值
int &c=a//ok,引用非常量左值
int &c=b;//error,引用常量左值,造成了常量变为可修改
int &c=123//error,引用右值,表达式结束临时对象已销毁。

常量左值引用可以引用所有左值和右值

const int &c=a;.......

右值引用

当然左值引用是有一定局限的,如常量左值引用的右值永远只能是常量。如果我们想获得非常量右值该怎么办呢。这时候c++11增加了新的引用类型 T&& t,来进行右值引用。
右值引用也分为常量右值引用和非常量右值引用,右值引用都不能用来引用左值。常量右值引用可以引用常量右值和非常量右值。而非常量右值引用只能引用非常量右值。

	const int  && a = 123;

move语义

语义

在说move语义只前先介绍下什么叫语义
语法 = 某个源代码怎么写
语义 = 这个源代码怎么执行
什么意思呢,就如泛型和正常代码的区别,泛型编程只会告诉你这个源代码怎么执行,在你确定类型后才是某个源代码怎么写。

赋值语义

在变量中经常用到赋值语义,赋值语义会先拷贝出一个临时变量,再将临时变量拷贝给左边的变量。在函数返回值中也是先产生临时变量再拷贝,这样每次赋值都会产生一次临时变量,当赋值复杂,如字符串,容器等将产生许多临时变量,降低效率。
如下,是赋值语义的两个语法:

int b=a[1];
int b=*(a+1);

move语义

所以为解决产生多余临时变量的问题,c++11中就出现了move语义,move语义就是把旧指针的值复制到新指针,并把旧指针的值赋为NULL。如果我们能确定某个值是一个非常量右值,则我们在进行临时对象的拷贝时,可以不用拷贝实际的数据,而只是“窃取”指向实际数据的指针,并将临时对象的生命周期提高,避免析构。(而我们之前提到的右值引用就是move语义提供的语法支持)
std::move 会传入一个 T&&的值,不用进行拷贝,但move后的变量仍然有效,但状态不明

string str1{"hello"};
string str2{"hello word "};
str1=std::move(str1);

猜你喜欢

转载自blog.csdn.net/qq_35651984/article/details/83451084
今日推荐