C++ move()函数案例详解
要了解move函数首先弄清左值引用和右值引用。
左值、左值引用、右值、右值引用
1、左值和右值的概念
左值是可以放在赋值号左边可以被赋值的值;左值必须要在内存中有实体;
右值当在赋值号右边取出值赋给其他变量的值;右值可以在内存也可以在CPU寄存器。
一个对象被用作右值时,使用的是它的内容(值),被当作左值时,使用的是它的地址。
2、引用
引用是C++语法做的优化,引用的本质还是靠指针来实现的。引用相当于变量的别名。
引用可以改变指针的指向,还可以改变指针所指向的值。
引用的基本规则:
- 声明引用的时候必须初始化,且一旦绑定,不可把引用绑定到其他对象;即引用必须初始化,不能对引用重定义;
- 对引用的一切操作,就相当于对原对象的操作。
3、左值引用和右值引用
3.1 左值引用
左值引用的基本语法:type &引用名 = 左值表达式;
3.2 右值引用
右值引用的基本语法type &&引用名 = 右值表达式;
右值引用在企业开发人员在代码优化方面会经常用到。
右值引用的“&&”中间不可以有空格。
- std::move并不能移动任何东西,它唯一的功能是将一个左值强制转化为右值引用,继而可以通过右值引用使用该值,以用于移动语义。从实现上讲,std::move基本等同于一个类型转换:static_cast<T&&>(lvalue);
- C++ 标准库使用比如vector::push_back 等这类函数时,会对参数的对象进行复制,连数据也会复制.这就会造成对象内存的额外创建, 本来原意是想把参数push_back进去就行了,通过std::move,可以避免不必要的拷贝操作。
- std::move是为性能而生。
- std::move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存的搬迁或者内存拷贝。
用法:
原lvalue值被moved from之后值被转移,所以为空字符串.
#include <iostream> #include <utility> #include <vector> #include <string> int main() { std::string str = "Hello"; std::vector<std::string> v; //调用常规的拷贝构造函数,新建字符数组,拷贝数据 v.push_back(str); std::cout << "After copy, str is \"" << str << "\"\n"; //调用移动构造函数,掏空str,掏空后,最好不要使用str v.push_back(std::move(str)); std::cout << "After move, str is \"" << str << "\"\n"; std::cout << "The contents of the vector are \"" << v[0] << "\", \"" << v[1] << "\"\n"; }
输出:
After copy, str is "Hello"
After move, str is ""
The contents of the vector are "Hello", "Hello"
到此这篇关于C++ move()函数案例详解的文章就介绍到这了,更多相关C++ move()函数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
相关推荐
-
C++ CopyFile,MoveFile用法案例详解
1.含义 CopyFile(A, B, FALSE);表示将文件A拷贝到B,如果B已经存在则覆盖(第三参数为TRUE时表示不覆盖) MoveFile(A, B);表示将文件A移动到B 2.函数原型 CopyFile: MoveFile: 由函数原型可以看出,这两个函数的前两个输入参数都为LRCWSTR类型,如果我们定义的是char*,记得转换成LRCWSTR,否则会报错: 另外,这两个函数都返回一个bool型变量,表示执行成功与否,当目标位置路径不存在时,会return 0 3.
-
C++中memcpy和memmove的区别总结
变态的命名 我们在写程序时,一般讲究见到变量的命名,就能让别人基本知道该变量的含义.memcpy内存拷贝,没有问题;memmove,内存移动?错,如果这样理解的话,那么这篇文章你就必须要好好看看了,memmove还是内存拷贝.那么既然memcpy和memmove二者都是内存拷贝,那二者究竟有什么区别呢? 先说memcpy 你有没有好好的参加过一场C++笔试.让你写出memcpy的实现,这是多么常见的笔试题啊.现在,拿起你的演算纸和笔;是的,是笔和纸,不是让你在你的IDE上写.写不出来?看下面吧:
-
C++11中value category(值类别)及move semantics(移动语义)的介绍
前言 C++11之前value categories只有两类,lvalue和rvalue,在C++11之后出现了新的value categories,即prvalue, glvalue, xvalue.不理解value categories可能会让我们遇到一些坑时不知怎么去修改,所以理解value categories对于写C++的人来说是比较重要的.而理解value categories离不开一个概念--move semantics.了解C++11的人我相信都了解了std::move,右值引用
-
C++中的移动构造函数及move语句示例详解
前言 本文主要给大家介绍了关于C++中移动构造函数及move语句的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 首先看一个小例子: #include <iostream> #include <cstring> #include <cstdlib> #include <vector> using namespace std; int main() { string st = "I love xing"; vec
-
C++11中std::move、std::forward、左右值引用、移动构造函数的测试问题
关于C++11新特性之std::move.std::forward.左右值引用网上资料已经很多了,我主要针对测试性能做一个测试,梳理一下这些逻辑,首先,左值比较熟悉,右值就是临时变量,意味着使用一次就不会再被使用了.针对这两种值引入了左值引用和右值引用,以及引用折叠的概念. 1.右值引用的举例测试 #include <iostream> using namespace std; //创建一个测试类 class A { public: A() : m_a(55) { } int m_a;
-
基于C++ list中erase与remove函数的使用详解
erase的作用是,使作为参数的迭代器失效,并返回指向该迭代器下一参数的迭代器.如下: 复制代码 代码如下: list ParticleSystem;list::iterator pointer;if(pointer->dead == true){ pointer = ParticleSystem.erase(pointer);} 有一段关于错误使用erase的程序 复制代码 代码如下: using namespace std;int main(){ std::listtest_list;
-
C++中CopyFile和MoveFile函数使用区别的示例分析
1.函数定义 CopyFile(A, B, FALSE);表示将文件A拷贝到B,如果B已经存在则覆盖(第三参数为TRUE时表示不覆盖) MoveFile(A, B);表示将文件A移动到B 2.函数原型 CopyFile: MoveFile: 由函数原型可以看出,这两个函数的前两个输入参数都为LRCWSTR类型,如果我们定义的是char*,记得转换成LRCWSTR,否则会报错: 另外,这两个函数都返回一个bool型变量,表示执行成功与否,当目标位置路径不存在时,会return 0 3.Demo 示
-
C++11右值引用和std::move语句实例解析(推荐)
右值引用(及其支持的Move语意和完美转发)是C++0x将要加入的最重大语言特性之一.从实践角度讲,它能够完美解决C++中长久以来为人所诟病的临时对象效率问题.从语言本身讲,它健全了C++中的引用类型在左值右值方面的缺陷.从库设计者的角度讲,它给库设计者又带来了一把利器.从库使用者的角度讲,不动一兵一卒便可以获得"免费的"效率提升- 下面用实例来深入探讨右值引用. 1.什么是左值,什么是右值,简单说左值可以赋值,右值不可以赋值.以下面代码为例,"A a = getA();&q
-
C++ move()函数案例详解
要了解move函数首先弄清左值引用和右值引用. 左值.左值引用.右值.右值引用 1.左值和右值的概念 左值是可以放在赋值号左边可以被赋值的值:左值必须要在内存中有实体: 右值当在赋值号右边取出值赋给其他变量的值:右值可以在内存也可以在CPU寄存器. 一个对象被用作右值时,使用的是它的内容(值),被当作左值时,使用的是它的地址. 2.引用 引用是C++语法做的优化,引用的本质还是靠指针来实现的.引用相当于变量的别名.
-
C语言之system函数案例详解
来看看在windows操作系统下system () 函数详解(主要是在C语言中的应用) 注意:在windows下的system函数中命令可以不区别大小写! 函数名: system 功 能: 发出一个DOS命令 用 法: int system(char *command); system函数已经被收录在标准c库中,可以直接调用. 例如: #include<stdio.h> #include<stdlib.h> int main() { printf("About to sp
-
C语言strtod()函数案例详解
前言 网上有很多关于strtod()函数的文章,不过大部分都是用strtod()函数转换一个字符 char *str = "111.11"; char *target; double ret; ret = strtod(str, &target); 很少有转换字符串的这样的用法 char *p = "111.11 -2.22 Nan nan(2) inF 0X1.BC70A3D70A3D7P+6 1.18973e+4932zzz"; 本文主要参考strtod
-
C++ WideCharToMultiByte()函数案例详解
函数WideCharToMultiByte() 详解 函数原型: int WideCharToMultiByte( UINT CodePage, DWORD dwFlags, LPWSTR lpWideCharStr, int cchWideChar, LPCSTR lpMultiByteStr, int cchMultiByte, LPCSTR lpDefaultChar, PBOOL pfUsedDefaultChar ); 函数功能: 此函数把宽字符串转换成指定的新的字符串,如ANSI,U
-
C语言 TerminateProcess函数案例详解
TerminateProcess 顾名思义,就是终止进程的意思. 是WindowsAPI的函数, 示例代码如下: // Demo.cpp : 定义控制台应用程序的入口点. //终止进程Demo #include "stdafx.h" using namespace std; //@param:dwpid:指定需要关闭的进程pid int CloseProcess(DWORD dwpid) { HANDLE hProcess = OpenProcess(PROCESS_TERMINATE
-
C语言 bind()函数案例详解
bind()函数介绍 在建立套接字文件描述符成功后,需要对套接字进行地址和端口的绑定,才能进行数据的接收和发送操作. 函数原型 bind()函数将长度为addlen的struct sockadd类型的参数my_addr与sockfd绑定在一起,将sockfd绑定到某个端口上,如果使用connect()函数则没有绑定的必要.绑定的函数原型如下: #include<sys/types.h> #include<sys/socket.h> int bind(in
-
CreateCompatibleDC()函数案例详解
函数功能:该函数创建一个与指定设备兼容的内存设备上下文环境(DC). 函数原型:HDC CreateCompatibleDC(HDC hdc): 参数: hdc:现有设备上下文环境的句柄,如果该句柄为NULL,该函数创建一个与应用程序的当前显示器兼容的内存设备上下文环境. 返回值:如果成功,则返回内存设备上下文环境的句柄:如果失败,则返回值为NULL. CreateCompatibleDc函数只适用于支持光栅操作的设备,应用程序可以通过调用GetDeviceCaps函数来确定一个设备是否支持这些
-
C# Directory.GetFiles()函数案例详解
C#中Directory.GetFiles() 函数的使用 C#中Directory.GetFiles(string path , string searchPattern, SearchOption searchOption ) 获取path目录中所有文件 注:红色字体部分为可选参数 参数 path 要搜索的目录的相对或绝对路径.此字符串不区分大小写. searchPattern 要与 path 中的文件名匹配的搜索字符串.此参数可以包含有效文本路径和通配符(* 和 ?)的组合(请参见"备注&
-
C语言 fseek(f,0,SEEK_SET)函数案例详解
fseek(f,0,SEEK_SET); 意思是把文件指针指向文件的开头 fseek 函数名: fseek 功 能: 重定位流上的文件指针 用 法: int fseek(FILE *stream, long offset, int fromwhere); 描 述: 函数设置文件指针stream的位置.如果执行成功,stream将指向以fromwhere为基准,偏移offset个字节的位置.如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置. 返回值: 成功,返回0,
-
C语言container of()函数案例详解
在linux 内核编程中,会经常见到一个宏函数container_of(ptr,type,member), 但是当你通过追踪源码时,像我们这样的一般人就会绝望了(这一堆都是什么呀? 函数还可以这样定义??? 怎么还有0呢??? 哎,算了,还是放弃吧...). 这就是内核大佬们厉害的地方,随便两行代码就让我们怀疑人生,凡是都需要一个过程,慢慢来吧. 其实,原理很简单: 已知结构体type的成员member的地址ptr,求解结构体type的起始地址.
随机推荐
- 使用nvm管理不同版本的node与npm的方法
- jQuery瀑布流插件Wookmark使用实例
- PHP制作图形验证码代码分享
- JAVA (Jsp)利用Google的Translate开发API的代码
- jsp实现文件上传下载的程序示例
- C#数据库操作小结
- Android在高jar包版本的工程中修改方法
- jquery常用操作小结
- js css后面所带参数含义介绍
- Maven优雅的添加第三方Jar包的方法
- 详解Android App中的AsyncTask异步任务执行方式
- IIS 浏览aspx页面出现无法显示XML页的解决方法分享
- PHP实现将浏览历史页面网址保存到cookie的方法
- C++11中std::declval的实现机制浅析
- Android进阶——安卓调用ESC/POS打印机打印实例
- 详细分析python3的reduce函数
- 利用Kotlin实现破解Android版的微信小游戏--跳一跳
- Pyinstaller将py打包成exe的实例
- python中的colorlog库详解
- Java+opencv3.2.0实现轮廓检测