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如何减少内存拷贝次数的更多相关文章

  1. emplace_back减少内存拷贝和移动

    --------<深入应用C++11:代码优化与工程级应用>第2章使用C++11改进程序性能,本章将分别介绍右值引用相关的新特性.本节为大家介绍emplace_back减少内存拷贝和移动. ...

  2. CUDA零内存拷贝 疑问考证

    今天思考了一下CUDA零内存拷贝的问题,感觉在即将设计的程序中会派上用场,于是就查了一下相关信息. 以下是一些有帮助的链接: cuda中的零拷贝用法--针对二维指针 cuda中的零拷贝用法--针对一维 ...

  3. python 变量作用域 v.__sizeof__() python 深复制 一切皆对象 尽量减少内存消耗

    python 深入理解 赋值.引用.拷贝.作用域 - 江召伟 - 博客园 https://www.cnblogs.com/jiangzhaowei/p/5740913.html a=[1,2,5]b= ...

  4. 将连续增长 N 次字符串所需的内存重分配次数从必定 N 次降低为最多 N 次 二进制安全

    SDS 与 C 字符串的区别 - Redis 设计与实现 http://redisbook.com/preview/sds/different_between_sds_and_c_string.htm ...

  5. Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

    Android XML shape 标签使用详解   一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...

  6. Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

    Android XML shape 标签使用详解   一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...

  7. CUDA内存拷贝

    原文链接1.cudaMemcpy()<--> cudaMalloc()  //线性内存拷贝 1 //线性内存拷贝 2 cudaMalloc((void**)&dev_A, data ...

  8. C# 处理应用程序减少内存占用

    SetProcessWorkingSetSize减少内存占用 系统启动起来以后,内存占用越来越大,使用析构函数.GC.Collect什么的也不见效果,后来查了好久,找到了个办法,就是使用 SetPro ...

  9. LeetCode-Repeated DNA Sequences (位图算法减少内存)

    Repeated DNA Sequences All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, ...

随机推荐

  1. Lintcode175-Revert Binary Tree-Easy

    175. Invert Binary Tree Invert a binary tree. Example Example 1: Input: {1,3,#} Output: {1,#,3} Expl ...

  2. jQuery页面替换+php代码实现搜索后分页

    HTML代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <ti ...

  3. 元注解——java.lang.annotation.Target(1.8)

    参考资料:https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Target.html 普通注解’只能用来注解’代码’,而’元注 ...

  4. Linux下Java环境安装

    本节主要讲解Linux(Centos 6.5)下Java环境的安装 1. 卸载机器上默认安装的JDK 在Linux环境下一般会默认安装jdk,为了自己项目的开发部署,一般情况要重新装jdk,而且自己装 ...

  5. guxh的python笔记七:抽象基类

    1,鸭子类型和白鹅类型 1.1,白鹅类型 白鹅类型对接口有明确定义,比如不可变序列(Sequence),需要实现__contains__,__iter__,__len__,__getitem__,__ ...

  6. photoshop打开图片显示的是索引,无法编辑解决

    问题如图: 解决方法: 这是因为图像模式是索引颜色,具体为啥图片打开是索引模式我也不是很清楚(捂脸),改成RGB颜色即可修改了 图像=>模式=>RGB颜色 如图:

  7. 数组和List以指定的方式拼接成字符串类型

    /// <summary> /// list转换成格式的字符串 /// </summary> /// <param name="param">拼 ...

  8. DNS及DNS有什么作用

    什么是DNS,DNS有什么作用: DNS(Domain Name System,域名系统),万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直 ...

  9. mysql 5.7版本的安装(非解压版)

    这次的开发项目数据库方面要用到mysql,为了更好的学习,就在本地安装了一个mysql 一:下载安装步骤: https://blog.csdn.net/qq_34952973/article/deta ...

  10. UVa 10905 - Children's Game 排序,题目没有说输入是int 难度: 0

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...