当前位置: 首页 > news >正文

网页版的游戏长沙关键词优化推荐

网页版的游戏,长沙关键词优化推荐,wordpress 做图库栏目,郑州浩方网站建设智联招聘目录 1. 引用 1.1 引用的概念 1.2 引用的特性 1.3 引用的使用场景 1.3.1 作为参数 1.3.2 作为返回值 1.4 常量引用 1.5 引用和指针的区别 2. 左值和右值 3. 右值引用 3.1 右值引用的概念 3.2 左值持久;右值短暂 3.3 变量是左值 3.4 标准库move函数 1.…

目录

1. 引用

1.1 引用的概念

1.2 引用的特性

1.3 引用的使用场景

1.3.1 作为参数

1.3.2 作为返回值

1.4 常量引用

1.5 引用和指针的区别

2. 左值和右值

3. 右值引用

3.1 右值引用的概念

3.2 左值持久;右值短暂

3.3 变量是左值

3.4 标准库move函数


1. 引用

C++11中新增了一种引用:右值引用(rvalue reference),主要用于内置类。严格来说,当我们使用术语“引用(reference)”时,指的其实是“左值引用(lvalue reference)”。

1.1 引用的概念

引用(reference)不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。

int a = 10;
int& ra = a;
//a为目标原名称,ra为目标引用名
//相当于给a取了一个别名叫ra
//a的地址和ra的地址相同

1.2 引用的特性

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体
int a = 10;
int b = 20;int& ra = a;//ok
int& ra;//err 引用在定义时必须初始化
int& c= a;//ok 一个变量可以有多个引用
int& ra = b;//err 引用一旦引用一个实体,再不能引用其他实体

1.3 引用的使用场景

1.3.1 作为参数

交换两个数的函数:

C语言版:修改变量,传变量的地址,再通过解引用,对变量进行操作

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}

C++版:修改变量,传变量的引用,对引用进行操作,就是对变量进行操作

void Swap(int& r1, int& r2)
{int tmp = r1;r1 = r2;r2 = tmp;
}

1.3.2 作为返回值

返回一个值(非引用):存在拷贝

返回引用:

1. 减少拷贝

2. 调用者可以修改返回对象

//静态顺序表
#define N 10typedef struct Array
{int a[N];int size;
}AY;int& PosAt(AY& ay, int i)
{assert(i < N);return ay.a[i];
}int main()
{AY ay;for (int i = 0; i < N; ++i){PosAt(ay, i) = i * 10;//修改返回对象}for (int i = 0; i < N; ++i){cout << PosAt(ay, i) << " ";}cout << endl;return 0;
}

如果出了函数作用域,对象还存在,则可以返回引用。

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。

1.4 常量引用

const修饰的引用,称为常量引用或常引用。不能通过常量引用改变对应的对象的值。

const int ci = 10;
const int &r1 = ci;//ok r1是常量引用,对应的对象ci也是常量
r1 = 20;//err 不能通过常量引用改变对应的对象的值
int &r2 = ci;//err ci不能改变,当然也就不能通过引用去改变ci//假设合法,则可以通过r2来改变ci,这是不合法的

在初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可。尤其,允许为一个常量引用绑定非常量的对象、字面值,甚至是个一般表达式。

int i = 50;
const int& r1 = i;//ok 将const int&绑定到一个普通int对象上
const int& r2 = 10;//ok 将const int&绑定到一个int字面值上
const int& r3 = r1 * 2;//ok 将const int&绑定到一个表达式上
int& r4 = r1 * 2;//err

我们要清楚当一个常量引用被绑定到另外一种类型上时到底发生了什么:

double pi = 3.14;
const int& rpi = pi;//ok 将const int&绑定到一个普通double对象上

为什么rpi能够绑定pi?为了让rpi绑定一个整型对象,编译器把代码处理为:

const int temp = pi;//隐式类型转换 double->const int
const int& rpi = temp;//让rpi绑定这个临时量

所以当一个常量引用被绑定到另外一种类型上时,常量引用绑定的其实是相同类型的临时量。

如果函数的返回值是一个值而非引用,那么返回的是一个临时变量,且具有常量性。如果要用引用接收该值,只能用常量引用。

int Count()
{static int n = 0;n++;return n;
}int& ret = Count();//err
const int& ret = Count();//ok

1.5 引用和指针的区别

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(4/8B)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

2. 左值和右值

C++的表达式要不然是右值(rvalue,读作"are-value"),要不然就是左值(lvalue,读作"ell-value")。这两个名词是从C语言继承过来的,原本是为了帮助记忆:左值可以位于赋值语句的左侧,右值则不能。

在C++语言中,二者的区别就没那么简单了。一个左值表达式的求值结果是一个对象或者一个函数,然而以常量对象为代表的某些左值实际上不能作为赋值语句的左侧运算对象。此外,虽然某些表达式的求值结果是对象,但它们是右值而非左值。可以做一个简单的归纳:当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。

不同的运算符对运算对象的要求各不相同,有的需要左值运算对象、有的需要右值运算对象;返回值也有差异,有的得到左值结果、有的得到右值结果。一个重要的原则(除右值引用)是在需要右值的地方可以用左值来代替,但是不能把右值当成左值(也就是位置)使用。当一个左值被当成右值使用时,实际使用的是它的内容(值)。到目前为止,已经有几种我们熟悉的运算符是要用到左值的。

  • 赋值运算符需要一个(非常量)左值作为其左侧运算对象,得到的结果也仍然是一个左值。
  • 取地址符作用于一个左值运算对象,返回一个指向该运算对象的指针,这个指针是一个右值。
  • 内置解引用运算符、下标运算符、迭代器解引用运算符、string和vector的下标运算符的求值结果都是左值。
  • 内置类型和迭代器的递增递减运算符作用于左值运算对象,其前置版本所得的结果也是左值。

3. 右值引用

3.1 右值引用的概念

为了支持移动操作,新标准引入了一种新的引用类型——右值引用(rvalue reference)。所谓右值引用就是必须绑定到右值的引用。我们通过&&而不是&来获得右值引用。如我们将要看到的,右值引用有一个重要的性质——只能绑定到一个将要销毁的对象。因此,我们可以自由地将一个右值引用的资源“移动”到另一个对象中。

左值和右值是表达式的属性。一些表达式生成或要求左值,而另外一些则生成或要求右值。一般而言,一个左值表达式表示的是一个对象的身份,而一个右值表达式表示的是对象的值。

类似任何引用,一个右值引用也不过是某个对象的另一个名字而已。如我们所知,对于常规引用(为了与右值引用区分开来,我们可以称之为左值引用(lvalue reference)),我们不能将其绑定到要求转换的表达式、字面常量或是返回右值的表达式。右值引用有着完全相反的绑定特性:我们可以将一个右值引用绑定到这类表达式上,但不能将一个右值引用直接绑定到一个左值上:

int i = 42;
int &r = i;            //正确:r引用i
int &&rr = i;          //错误:不能将一个右值引用绑定到一个左值上
int &r2 = i * 42;      //错误:i*42是一个右值
const int &r3 = i * 42;//正确:我们可以将一个const的引用绑定到一个右值上
int &&rr2 = i * 42;    //正确:将rr2绑定到乘法结果上

返回左值引用的函数,连同赋值、下标、解引用和前置递增/递减运算符,都是返回左值的表达式的例子。我们可以将一个左值引用绑定到这类表达式的结果上。

返回非引用类型的函数,连同算术、关系、位以及后置递增/递减运算符,都生成右值。我们不能将一个左值引用绑定到这类表达式上,但我们可以将一个const的左值引用或者一个右值引用绑定到这类表达式上。

3.2 左值持久;右值短暂

考察左值和右值表达式的列表,两者相互区别之处就很明显了:左值有持久的状态,而右值要么是字面常量,要么是在表达式求值过程中创建的临时对象。

由于右值引用只能绑定到临时对象,我们得知

  • 所引用的对象将要被销毁
  • 该对象没有其他用户

这两个特性意味着:使用右值引用的代码可以自由地接管所引用的对象的资源。

右值引用指向将要被销毁的对象。因此,我们可以从绑定到右值引用的对象“窃取”状态。

3.3 变量是左值

变量可以看作只有一个运算对象而没有运算符的表达式,虽然我们很少这样看待变量。类似其他任何表达式,变量表达式也有左值/右值属性。变量表达式都是左值。带来的结果就是,我们不能将一个右值引用绑定到一个右值引用类型的变量上,这有些令人惊讶:

int &&rr1 = 42; //正确:字面常量是右值
int &&rr2 = rr1;//错误:表达式rr1是左值!

其实有了右值表示临时对象这一观察结果,变量是左值这一特性并不令人惊讶。毕竟,变量是持久的,直至离开作用域时才被销毁。

变量是左值,因此我们不能将一个右值引用直接绑定到一个变量上,即使这个变量是右值引用类型也不行。

3.4 标准库move函数

虽然不能将一个右值引用直接绑定到一个左值上,但我们可以显式地将一个左值转换为对应的右值引用类型。我们还可以通过调用一个名为move的新标准库函数来获得绑定到左值上的右值引用,此函数定义在头文件utility中。move函数返回给定对象的右值引用。

int &&rr3 = std::move(rr1);//ok

move调用告诉编译器:我们有一个左值,但我们希望像一个右值一样处理它。我们必须认识到,调用move就意味着承诺:除了对rr1赋值或销毁它外,我们将不再使用它。在调用move之后,我们不能对移后源对象的值做任何假设。

我们可以销毁一个移后源对象,也可以赋予它新值,但不能使用一个移后源对象的值。

如前所述,与大多数标准库名字的使用不同,对move我们不提供using声明。我们直接调用std::move而不是move。

使用move的代码应该使用std::move而不是move。这样做可以避免潜在的名字冲突。

http://www.ds6.com.cn/news/1562.html

相关文章:

  • 做数据新闻的网站苏州吴中区seo关键词优化排名
  • 公司营销型网站建设专门做推广的软文
  • 简述网站开发工作流程神马搜索seo优化排名
  • 数据库修改wordpress登录密码石家庄seo关键词
  • t恤定制网站上海百度移动关键词排名优化
  • 用软件做的网站权限友情链接交换方式有哪些
  • 前端培训机构优化生育政策
  • 城乡建设部网站自助商品房网络营销推广总结
  • wordpress文章模版西安seo管理
  • 同信.长春网站建设搜索自媒体平台
  • ubuntu下载wordpress快速整站排名seo教程
  • 一级做爰片a视频网站如何在国外推广自己的网站
  • 网站建设服务清单windows优化大师提供的
  • 手机网站制作注意事项cilimao磁力猫搜索引擎
  • 中国十大网站建设企业网站设计代码
  • 可以做mv的视频网站营销传播服务
  • 爬虫 网站开发实例旺道seo工具
  • 一级a做网站免费合肥seo排名扣费
  • 潮州市建设局官方网站爱站网域名查询
  • 哪些网站是单页面湖南正规seo优化
  • 做b2b需要建网站吗上百度首页
  • 好的网站建设网百度竞价排名怎么收费
  • 淘宝客导购网站怎么做网站统计系统
  • 美国一级a做爰片免费网站 视频播放网站排名推广工具
  • 网站建设网站定制开发整站优化seo平台
  • 建筑施工特种证书查询入口官网做网站seo怎么赚钱
  • 东莞中小企业网站制作seo研究中心晴天
  • 哪里有门户网站开发外包公司值得去吗
  • 济南网站优化推广做网络推广有前途吗
  • 手机哪里可以做视频网站如何做关键词优化