C++虐我千百遍,我待C++如初恋


从智能指针说起
对高手而言。指针是上天入地的神器。对新手而言,那简直是灾难的源泉。高级语言如Java,C#都自己主动管理内存。你仅仅管new。不必担心内存释放问题。Bjarne StroustrupC觉得++增加垃圾回收机制将做不适合系统底层的开发,为此C++提倡使用RAII来管理资源。

auto_ptr就是依据这样的理念而诞生的智能指针,本意是想编写个效率接近原生指针,但具有资源全部权安全的智能指针。当发生赋值,拷贝构造时,全部权就发生转移。

这就显的非常鸡肋,不能放入STL容器中,由于它的拷贝构造和传统的拷贝构造不一样。


unique_ptr代替auto_ptr
C++11的右值引用和move语义攻克了这个问题,于是乎unique_ptr代替auto_ptr。

为什么unique_ptr能够放入容器呢?如:

vector<unique_ptr<Song>> v;
v.push_back(unique_ptr<Song>(new Song("B'z","Juice")));

答案是unique_ptr能够move,不能copy。它没有拷贝构造。拷贝赋值,可是有move构造,move赋值。

虽然能够放入容器内,但不是全部函数都是能够用的。当然了,必要的时候能够使用std::move来将左值转化为右值。


如今。有这么一个问题。unique_ptr没有copy函数,那么。函数是怎样返回unique_ptr的呢?比方C++14就有个make_unique的模板函数返回了unique_ptr。我们来看看他的实现:
template<class T,     class... Types>
unique_ptr<T> make_unique(Types&&... Args)
{
    return (unique_ptr<T>(new T(forward<Types>(Args)...)));   
}
这个函数会调用拷贝构造吗,一開始我也非常迷惑,经过一番查找之后。基本能够确认不会调用拷贝构造。


RVO和NRVO
当函数返回一个对象时。理论上会产生暂时变量。那必定是会导致新对象的构造和旧对象的析构,这对效率是有影响的。

C++编译针对这样的情况同意进行优化,哪怕是构造函数有副作用。这叫做返回值优化(RVO),返回有名字的对象叫做具名返回值优化(NRVO),就那RVO来说吧,本来是在返回时要生成暂时对象的。如今构造返回对象时直接在接受返回对象的空间中构造了。如果不进行返回值优化。那么上面返回unique_ptr会不会有问题呢?也不会。由于标准同意编译器这么做:

1.假设支持move构造,那么调用move构造。
2.假设不支持move。那就调用copy构造。
3.假设不支持copy,那就报错吧。

显然的。unique_ptr是支持move构造的,unique_ptr对象能够被函数返回。

duang!!!为什么函数能够返回unique_ptr的更多相关文章

  1. Entity Framework 6 Recipes 2nd Edition(11-6)译 -> 从一个”模型定义”函数里返回一个复杂类型

    11-6.从一个”模型定义”函数里返回一个复杂类型 问题 想要从一个”模型定义”函数返回一个复杂类型 解决方案 假设我们有一个病人(patient)和他们访客(visit)的模型,如 Figure 1 ...

  2. 测试函数用Return 返回值和用函数名返回值的区别

    '*************************************************************************'**模 块 名:工程1 - Form1'**说   ...

  3. Shell入门教程:Shell函数的返回值

    shell函数返回值一般有3种方式: 1.return语句(默认的返回值) shell函数的返回值可以和其他语言的返回值一样,通过return语句返回. 比如: #!/bin/bash functio ...

  4. UNIX 系统调用函数errno返回值搜集(in updating )

    当Unix系统级函数遇到错误时,它们会典型地返回-1,并设置全局整数变量errno来表示什么出错了 阅读redis源码的时候,发现如果对系统级函数出错时的errno比较熟悉,写起程序来会游刃有余不少. ...

  5. GDB 修改当前判断函数的返回值(即修改寄存器的值)的方法

    工作中遇到的问题: 在GDB调试时要进入下边该判断后边的函数,而m_EtherDecode.Chk_MakeSure_IP_Pkt(pPacket,dwPacketLen)的返回值是false,所以需 ...

  6. 面试题-->写一个函数,返回一个数组中所有元素被第一个元素除的结果

    package com.rui.test; import java.util.Random; /** * @author poseidon * @version 1.0 * @date:2015年10 ...

  7. JAVA函数的返回值类型详解以及生成随机数的例题

    函数的四要素:函数名.输入.输出(返回).加工. 函数分为两种:一种是有返回值得函数,一种是没有返回值的函数. 1. 定义:没有返回值的函数:(当我不需要函数的计算结果再拿出来进行运算的时候,我就不需 ...

  8. JavaScript 在函数中使用Ajax获取的值作为函数的返回值

    解决:JavaScript 在函数中使用Ajax获取的值作为函数的返回值,结果无法获取到返回值 原因:ajax默认使用异步方式,要将异步改为同步方式 案例:通过区域ID,获取该区域下所有的学校 var ...

  9. c++特性:指向类成员的指针和非类型类模板参数和函数指针返回值 参数推导机制和关联型别

    一.c++允许定义指向类成员的指针,包括类函数成员指针和类数据成员指针 格式如下: class A { public: void func(){printf("This is a funct ...

随机推荐

  1. poj 3259 Wormholes 【SPFA&amp;&amp;推断负环】

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36852   Accepted: 13502 Descr ...

  2. 简单的Queue

    不考虑好多东西,算法考试中用得到的Queue #include<iostream> using namespace std; const int MAX = 100; struct MyQ ...

  3. 用 C 语言编写一个简单的垃圾回收器

    人们似乎觉得编写垃圾回收机制是非常难的,是一种仅仅有少数智者和Hans Boehm(et al)才干理解的高深魔法.我觉得编写垃圾回收最难的地方就是内存分配,这和阅读K&R所写的malloc例 ...

  4. gwt学习资料

    学习资料: 2 3

  5. IT关键词,面试知识问与答

    二叉树遍历的三种方式? 遍历是指依次访问⼆叉树中的每个元素.有三种遍历⽅法,分别是前序遍历. 中序遍历和后序遍历.它们是按照访问根节点和⼦节点的先后顺序命名的. • 前序遍历:先访问根节点,然后访问左 ...

  6. webrtc所有平台下载编译步骤详细说明

    webrtc所有平台下载编译步骤详细说明 1.安装depot tools Windows:国外下载:https://storage.googleapis.com/chrome-infra/depot_ ...

  7. Regexp-Utils:身份证号校验

    ylbtech-Regexp-Utils:身份证号校验 1.返回顶部 1.方法 var idCardNoUtil = { /*省,直辖市代码表*/ provinceAndCitys: { 11: &q ...

  8. spring Ioc Aop整合

    之前用DWP项目做spring的IOC,xml总是提示有问题,之后改用maven通过. 之后将这一块的内容补充. 仔细考虑一下spring 的IOC是无处不在的,演示Aop也需要依赖spring的IO ...

  9. Java Servlet 配置

    图片太大,可以右键另存再查看,也可以鼠标点击拖置一下,用浏览器单独承载放大查看.

  10. Memcache相关面试题

    1)memcached的cache机制是怎样的? 懒惰算法 +最近最少使用原则 2)memcached如何实现冗余机制? 冗余:就是有好多好多不经常使用的. 可以不用实现冗余机制,如果非要实现.那就搞 ...