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. linux下jenkins安装

    在安装jenkins之前.首先确认jdk和tomcat,maven已经配置好 详细配置方法,请看的我博客. jdk:jdk的安装与配置 tomcat:tomcat的安装与配置 maven:maven的 ...

  2. c3---scanf

    #include <stdio.h> int main(int argc, const char * argv[]) { // 要求: 存储用户输入的整数 // 1.用户输入的整数确定吗? ...

  3. 蓝桥杯-- 历届试题 核桃的数量 (gcd)

      历届试题 核桃的数量   时间限制:1.0s   内存限制:256.0MB        问题描述 小张是软件项目经理,他带领3个开发组.工期紧,今天都在加班呢.为鼓舞士气,小张打算给每个组发一袋 ...

  4. bfs初学

    BFS: ** 当知道初始和目标状态的,用双向BFS: 无权图最好用BFS 不用重复如队** 实现框架: 抄来的(来源:https://www.luogu.org/blog/stephen2333/s ...

  5. Spark on YARN运行模式(图文详解)

    不多说,直接上干货! 请移步 Spark on YARN简介与运行wordcount(master.slave1和slave2)(博主推荐) Spark on YARN模式的安装(spark-1.6. ...

  6. 欢迎来到Flask的世界

    不多说,直接上文档链接:Flask的文档 教程 API 快速上手

  7. Bluefish Editor - 蓝鱼编辑器 for Web Designer

    Bluefish is a GTK+ HTML editor for the experienced web designer. Its features include nice wizards f ...

  8. Request.QueryString["id"] 、Request.Params["id"] 的强大

    <form> <input type="text" name="id" value="值"> </form&g ...

  9. string 去除空格

      /** * 去除空格 * @param {str} * @param {type} * type: 1-所有空格 2-前后空格 3-前空格 4-后空格 * @return {String} */ ...

  10. layer-list

    <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android=" ...