win编程实践(5)【c++】- 右值引用

右值引用形式:类型 && a= 被引用的对象。

与左值引用&的区别在于:右值是临时变量, 可理解为右值的引用,右值初始化后临时变量消失。

从实践角度讲,它能够完美解决C++中长久以来为人所诟病的临时对象效率问题。从语言本身讲,它健全了C++中的引用类型在左值右值方面的缺陷。从库设计者的角度讲,它给库设计者又带来了一把利器。从库使用者的角度讲,不动一兵一卒便可以获得“免费的”效率提升…

在标准C++语言中,临时量(术语为右值,因其出现在赋值表达式的右边)可以被传给函数,但只能被接受为const &类型。这样函数便无法区分传给const &的是真实的右值还是常规变量。而且,由于类型为const &,函数也无法改变所传对象的值。C++0x将增加一种名为右值引用的新的引用类型,记作typename &&。这种类型可以被接受为非const值,从而允许改变其值。这种改变将允许某些对象创建转移语义。比如,一个std::vector,就其内部实现而言,是一个C式数组的封装。如果需要创建vector临时量或者从函数中返回vector,那就只能通过创建一个新的vector并拷贝所有存于右值中的数据来存储数据。之后这个临时的vector则会被销毁,同时删除其包含的数据。有了右值引用,一个参数为指向某个vector的右值引用的std::vector的转移构造器就能够简单地将该右值中C式数组的指针复制到新的vector,然后将该右值清空。这里没有数组拷贝,并且销毁被清空的右值也不会销毁保存数据的内存。返回vector的函数现在只需要返回一个std::vector<>&&。如果vector没有转移构造器,那么结果会像以前一样:用std::vector<> &参数调用它的拷贝构造器。如果vector确实具有转移构造器,那么转移构造器就会被调用,从而避免大量的内存分配。

本博客所有内容是原创,如果转载请注明来源

http://blog.csdn.net/myhaspl/

右值引用

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//code:http://blog.csdn.net/myhaspl

#include "stdafx.h"
#include <iostream>
using std::endl;
using std::cout;
using std::cin;

class Mypoint{
public:
int n_x = 0;
int n_y = 0;
//code:http://blog.csdn.net/myhaspl
Mypoint(int x, int y) {
n_x = x;
n_y = y;
cout << n_x << "," << n_y;
cout << "  create!" << endl;
}
Mypoint(const Mypoint &myp) {
n_x = myp.n_x;
n_y = myp.n_y;
cout << n_x << "," << n_y;
cout << "  拷贝构造函数调用!" << endl;
}
Mypoint(Mypoint &&myp) {
n_x = myp.n_x;
n_y = myp.n_y;
cout << n_x << "," << n_y;
cout << "  move拷贝构造函数调用!" << endl;
}
~Mypoint() {
cout << n_x << "," << n_y;
cout << "  delete!" << endl;
}
};

int mydistance(const Mypoint &p1, const Mypoint &p2) {
cout << "Mypoint& distance!" << endl;
return static_cast<int>(sqrt((p2.n_x - p1.n_x)*(p2.n_x - p1.n_x) + (p2.n_y - p1.n_y)*(p2.n_y - p1.n_y)));
}

int mydistance(Mypoint &&p1, Mypoint &&p2) {
cout << "Mypoint&& distance!" << endl;
return static_cast<int>(sqrt((p2.n_x - p1.n_x)*(p2.n_x - p1.n_x) + (p2.n_y - p1.n_y)*(p2.n_y - p1.n_y)));
}

int main()
{
int x = 10;
int y = 100;
char temp = ‘ ‘;
int &xleftptr = x;
xleftptr = 20;
cout << xleftptr << endl;

Mypoint myp1= Mypoint(10,20);
Mypoint myp2 = Mypoint(100, 200);
Mypoint myp3 = Mypoint(88, 99);
Mypoint lp3 = myp3;
Mypoint &lp1 = myp1;
Mypoint &lp2 = myp2;
//---左值引用
cout << "左值引用result:" << mydistance(myp1, myp2) << endl;
//---右值引用
cout <<"右值引用result:"  << mydistance(Mypoint(110, 220), Mypoint(1100, 2200)) << endl;
cin >> temp;
return 0;
}

本博客所有内容是原创,如果转载请注明来源

http://blog.csdn.net/myhaspl/

20
10,20  create!
100,200  create!
88,99  create!
88,99  拷贝构造函数调用!
Mypoint& distance!
左值引用result:201
1100,2200  create!
110,220  create!
Mypoint&& distance!
右值引用result:2213
110,220  delete!
1100,2200  delete!

本博客所有内容是原创,如果转载请注明来源

http://blog.csdn.net/myhaspl/

时间: 2024-10-20 15:45:56

win编程实践(5)【c++】- 右值引用的相关文章

C++11中的右值引用及move语义编程

C++0x中加入了右值引用,和move函数.右值引用出现之前我们只能用const引用来关联临时对象(右值)(造孽的VS可以用非const引用关联临时对象,请忽略VS),所以我们不能修临时对象的内容,右值引用的出现就让我们可以取得临时对象的控制权,终于可以修改临时对象了!而且书上说配合move函数,可以大大提高现有C++的效率.那么是怎样提高它的效率的呢?看段代码先! #include <iostream> #include <utility> #include <vector

第二十四章 C++11特性之右值引用

右值引用,是 C++11 语言核心中最为重要的改进之一.右值引用给 C++ 带来了“Move语义”(“转移语义”),同时解决了模板编程中完美转发的问题(Perfect forwarding).右值引用使 C++ 对象有能力甄别什么是(可以看作)临时对象,对于临时对象的拷贝可以做某种特别的处理,一般来说主要是直接传递资源的所有权而不是像一般地进行拷贝,这就是所谓的 move 语义了.完美转发则是指在模板编程的时候,各层级函数参数传递时不会丢失参数的“属性”(lvalue/rvalue, const

详解C++右值引用

http://jxq.me/2012/06/06/%E8%AF%91%E8%AF%A6%E8%A7%A3c%E5%8F%B3%E5%80%BC%E5%BC%95%E7%94%A8/#thbecker C++0x标准出来很长时间了,引入了很多牛逼的特性[1].其中一个便是右值引用,Thomas Becker的文章[2]很全面的介绍了这个特性,读后有如醍醐灌顶,翻译在此以便深入理解. 目录 概述 move语义 右值引用 强制move语义 右值引用是右值吗? move语义与编译器优化 完美转发:问题

[C++]右值引用和转移语义

右值引用和转移语义 本文尝试着解释何为右值引用和转移语义以及使用它们具有优势,并提供相关案例分析. 定义 左值和右值 首先我们先来理解一下什么是左值和右值. C/C++语言中可以放在赋值符号左边的变量,左值表示存储在计算机内存的对象,左值相当于地址值.右值:当一个符号或者常量放在操作符右边的时候,计算机就读取他们的"右值",也就是其代表的真实值,右值相当于数据值. C/C++语言中可以放在赋值符号左边的变量,即具有对应的可以由用户访问的存储单元,并且能够由用户去改变其值的量.左值表示存

(译)C++11中的Move语义和右值引用

郑重声明:本文是笔者网上翻译原文,部分有做添加说明,所有权归原文作者! 地址:http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html C++一直致力于生成快速的程序.不幸的是,直到C++11之前,这里一直有一个降低C++程序速度的顽症:临时变量的创建.有时这些临时变量可以被编译器优化(例如返回值优化),但是这并不总是可行的,通常这会导致高昂的对象复制成本.我说的是怎么回事呢? 让我们

C++标准库之右值引用相关:引用折叠

引用折叠 引用折叠出现的情况在于范型编程时. void f(T&& param); f(10); int x = 10; f(x); 这两者都可运行成功. 由于存在T&&这种未定的引用类型,当它作为参数时,有可能被一个左值引用或右值引用的参数初始化,这是经过类型推导的T&&类型,相比右值引用(&&)会发生类型的变化,这种变化就称为引用折叠.(<深入应用C++11-代码优化与工程级应用> --- 祁宇 P68 ) 引用折叠的规则如下

[转]C++11 左值、右值、右值引用详解

https://blog.csdn.net/hyman_yx/article/details/52044632 左值.右值 在C++11中所有的值必属于左值.右值两者之一,右值又可以细分为纯右值.将亡值.在C++11中可以取地址的.有名字的就是左值,反之,不能取地址的.没有名字的就是右值(将亡值或纯右值).举个例子,int a = b+c, a 就是左值,其有变量名为a,通过&a可以获取该变量的地址:表达式b+c.函数int func()的返回值是右值,在其被赋值给某一变量前,我们不能通过变量名

第13课 右值引用

一. 左值和右值 (一)概述 1. 左值是一般指表达式结束后依然存在的持久化对象.右值指表达式结束时就不再存在的临时对象.便捷的判断方法:能对表达式取地址.有名字的对象为左值.反之,不能取地址.匿名的对象为右值. 2. C++ 表达式(运算符带上其操作数.字面量.变量名等)可按照两种独立的属性:类型和值类别 (value category).而表达式的值类别必属于左值.纯右值或将亡值三者之一.如int&& x;当x用于表达式时,其类型为右值引用,但值类别为左值(因为有名字) (二)右值的分

C11右值引用

 int *a = &1; //1为右值 不可取址  const int &&aa = 1;// 右值引用,    //注意  考虑到安全因素,具名变量即使被声明为右值类型也不会被当作右值 而要用std::move函数