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, ...
随机推荐
- 力扣(LeetCode)605. 种花问题
假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. 给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花 ...
- .gitignore无效
有个别文件不想跟踪,比如pycharm的配置文件. 但是这个文件已经被git跟踪的情况下,再加入.gitignore是无效的. 只需要: git rm --cached .idea/workspace ...
- dedecms 在模版页面获取当前栏目id
在模版中单独调用当前栏目id {dede:type}[field:ID /]{/dede:type} 在{dede:sql}中调用当前栏目id {dede:sql sql='Select * from ...
- laravel进行单元测试的时候如何模拟数据库以及mockery的调用
单元测试是独立的,所谓的独立是指有独立的运行容器,独立的数据库. 这样做有什么好处呢? (1). 不会跟正常的容器产生冲突,继而影响正常业务. (2). 数据库独立防止数据被修改影响单元测试结果. 这 ...
- selenium选择器_css属性选择器
搜索 <button class="btn-search tb-bg" type="submit" data-spm-click="gostr= ...
- Linux下更换jdk和配置环境变量
目前Linux上安装的是jdk7的java环境,由于项目原因需要升级到jdk8,无需卸载掉原本的jdk7,按如下简单步骤即可: 参考了:https://www.cnblogs.com/jiu0821/ ...
- WEB UI做TREE
效果图: 原本的普通搜索帮助,改成上面这样层级的搜索帮助.这里只做了两级. 一,新建一个TREE节点 1.新建tree结构:ZGRTEXT 2.新建树叶节点处理类: 修改超类为CL_BSP_WD_TR ...
- JavaScript 复杂判断的更优雅写法
我们编写js代码时经常遇到复杂逻辑判断的情况,通常大家可以用if/else或者switch来实现多个条件判断,但这样会有个问题,随着逻辑复杂度的增加,代码中的if/else/switch会变得越来越臃 ...
- QComboBox样式
https://blog.csdn.net/lys211/article/details/43956979https://blog.csdn.net/x_nazgul/article/details/ ...
- Eclipse中Server视图加载项目之后项目名后边有带括号的名字
用习惯了eclipse工具,因为某种原因需要修改项目名称.结果选择项目,按“F2”成功修改后,使用tomcat进行web发布时,选择“Add and Remove”,发现名字还是以前那个项目名称.即使 ...