C++11如何减少内存拷贝次数
C++11中出现了很多迷人的特性。例如智能指针实现高效的内存管理,std::bind和std::function函数封装器,以及lambda实现的函数对象语法糖,都是使我着迷的地方。
而C++11最大的改动则是移动语义,考虑这么一个场景:将一个将亡对象A的内容拷贝给另一个对象B,然后A对象被析构释放内存,我们的程序使用B对象。这是经常发生的事情,调用函数传参或者函数返回值时最为常见。如果A和B对象占用的内存非常多,则这个操作会导致大量内存的拷贝。
为什么我们不直接将对象A的名字改成B呢?这样就省去了拷贝内存和析构的时间,增加的只是重命名的时间,在对象所占内存巨大时(例如对象是一个高度为1000的平衡二叉树(std::map),每个节点又是一个庞大的自定义结构体)。
是的,为了这个目的,C++作出了很多的努力,引用传参就能实现为对象取一个别名的作用,然而这一套别名系统必须保证原对象存在,如果原对象超出作用域被析构,则所有关于这个对象的别名都会立刻失效,这一个对象的持有者还是它自身,只是使用别名可以在对象存在期间引用它。
想要改变持有者,则可以使用智能指针,多个指针同时持有一个对象,当最后一个指针析构时会将指向的对象析构,这使得对象可以被多个指针持有,这是智能指针与引用语法的一个区别,并且智能指针是靠库实现,而引用是靠语法支持。而智能指针有一个非常大的特点,它有权力析构对象,意味着它所指向的内容必须是堆区内容,而栈上的内容则靠出栈时自动析构释放内存,如果你的大体积的对象是放在栈上,则使用智能指针是不行的。
移动语义的发明,就能解决这个问题,不管发生栈上或者堆上 大体积对象的拷贝,就可以使用移动语义,改变该对象的持有者,而不需要拷贝这块内存。还是最初 将亡值A拷贝到B的例子,依靠移动语义,拷贝时使B指向A的内容,然后A指向B的内容(也就是交换内容,注意这里的交换没有发生大内存拷贝,只是改变了指针的指向。)然后A对象释放,我们接着使用B对象,B对象的内容是A原来的内容,而A对象析构时将B对象原本要被覆盖的内容析构掉,完美。
C++从引用语法、智能指针类、移动语义多个方面支持开发者减少内存的拷贝,发挥出C++的性能威力。在设计良好的情况下,不会出现大内存块的拷贝。
C++11如何减少内存拷贝次数的更多相关文章
- emplace_back减少内存拷贝和移动
--------<深入应用C++11:代码优化与工程级应用>第2章使用C++11改进程序性能,本章将分别介绍右值引用相关的新特性.本节为大家介绍emplace_back减少内存拷贝和移动. ...
- CUDA零内存拷贝 疑问考证
今天思考了一下CUDA零内存拷贝的问题,感觉在即将设计的程序中会派上用场,于是就查了一下相关信息. 以下是一些有帮助的链接: cuda中的零拷贝用法--针对二维指针 cuda中的零拷贝用法--针对一维 ...
- python 变量作用域 v.__sizeof__() python 深复制 一切皆对象 尽量减少内存消耗
python 深入理解 赋值.引用.拷贝.作用域 - 江召伟 - 博客园 https://www.cnblogs.com/jiangzhaowei/p/5740913.html a=[1,2,5]b= ...
- 将连续增长 N 次字符串所需的内存重分配次数从必定 N 次降低为最多 N 次 二进制安全
SDS 与 C 字符串的区别 - Redis 设计与实现 http://redisbook.com/preview/sds/different_between_sds_and_c_string.htm ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- CUDA内存拷贝
原文链接1.cudaMemcpy()<--> cudaMalloc() //线性内存拷贝 1 //线性内存拷贝 2 cudaMalloc((void**)&dev_A, data ...
- C# 处理应用程序减少内存占用
SetProcessWorkingSetSize减少内存占用 系统启动起来以后,内存占用越来越大,使用析构函数.GC.Collect什么的也不见效果,后来查了好久,找到了个办法,就是使用 SetPro ...
- LeetCode-Repeated DNA Sequences (位图算法减少内存)
Repeated DNA Sequences All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, ...
随机推荐
- Learning-MySQL【2】:MySQL存储引擎及数据库的操作管理
一.存储引擎 存储引擎实际上就是如何存储数据.如何为存储的数据建立索引和如何更新.查询数据.存储引擎也可以称为表类型. MySQL提供了插件式(pluggable)的存储引擎,存储引擎是基于表的.同一 ...
- Github 最简单的认证方式 - Access Token
Github 本身提供了多种认证方式,所有开发人员可以各取所需. SSH,这是最原始的方式,如果使用git bash只要按照官方文档一步一步配置就好了 小心坑:SSH有可能需要配置代理,否则无法解析服 ...
- 【搬运】Wget 命令详解
用过 Linux 系统的对于 wget 不陌生吧,从网上下载资源等操作都是少不了它,它体积小但功能集全,支持 FTP HTTP HTTPS 协议下载方式,支持断点续传 代理服务器. 现在 Window ...
- C# wnform 请求http ( get , post 两种方式 )
1.Get请求 string strURL = "http://localhost/WinformSubmit.php?tel=11111&name=张三";System. ...
- CTime格式化
CTime Formateg://CString date = time.Format("%Y-%m-%d %H:%M:%S %W-%A");格式符号说明 %a —— 星期(缩写英 ...
- 第K个幸运数字(4、7)
题目:4和7是两个幸运数字,我们定义,十进制表示中,每一位只有4和7两个数的正整数都是幸运数字,前几个幸运数字为:4,7,44,47,74,77,444,447······输出第K个数字. 思路是:将 ...
- Descriptors;Hello1 project中的Web.xml
Deployment Descriptors(描述符)是一个xml文件,用来描述如何部署一个模块或者应用(根据描述符中定义的配置和容器选项).举例来说,一个EJB的部署描述符会向EJB容器传递如何管理 ...
- 【转】阿里云免费SSL证书申请与安装使用(IIS7)
阅读目录 准备: 第一步:免费SSL证书申请 第二步:证书导入 第三步:分配服务器证书 最后一步:访问测试 回到顶部 准备: 阿里云已完成备案的域名一个 回到顶部 第一步:免费SSL证书申请 登陆阿里 ...
- vue中提示toFixed不是函数
vue中toFixed获取小数点后两位 错误提示:.toFixed is not a function解决办法:Number(_this.group_cash).toFixed(2) 转自:http ...
- javascript 位操作符
not: 按位非,符号为波浪线~ 作用吧二进制数的所有位进行非操作,对应的十进制结果为原先10进制数字取负值然后减去1 其他的操作符感觉不是很常用,分别为按位与(&),按位或(|),左移(&l ...