C++ 11标准库引入了几种智能指针

unique_ptr

shared_ptr

weak_ptr

C++内存管理机制是当一个变量或对象从作用域过期的时候就会从内存中将他干掉。但是如果变量只是一个指针的话,干掉的就只是指针自身,而指针所指向的内存还是存在的,这就是所谓的内存泄漏。智能指针的出现就是为了解决这个问题。

智能指针的大体原理:当智能指针对象过期的时候,会执行智能指针对象的析构函数,在这里我们选择进行对所指堆对象的清除操作。

智能指针的头文件是

#include<memory>

定义在标准库命名空间 std 当中

其中:

unique_ptr是不允许复制操作的,所以一个unique_ptr不能直接赋值给另一个unique_ptr或者其他类型的智能指针。unique_ptr重载了->运算符可以直接寻找对应对象的

内容。它自始至终都是一个对象对应一个智能指针,绝对不允许把同一个对象赋值给两个unique_ptr指针,同时,一旦一个对象赋值给一个unique_ptr那么将不会有别的智能指针去被这个对象赋值。

如果我们想更改对象的赋值,我们智能使用std::move方法,这个方法废掉了原来的unique_ptr,使之变为无用的智能指针,然后赋值给一个新的智能指针。

shared_ptr则相反,它可以有很多个实例管理同一个堆对象,每增加一个实例,引用计数+1,过期一个实例,引用计数-1。当引用计数为0的时候释放堆内存。

weak_ptr不能直接用->获取对象的内容,需要调用lock()方法获得对象。此外使用方法和shared_ptr类似,但是不参与引用计数的计算。

接下来打算用一组实例来直观的反映一下智能指针的使用

#include<iostream>
#include<memory>
#include<string>
#include<functional>

using namespace std;

class poco_one
{
public:
    poco_one(string n);
    ~poco_one();

public:
    void showDesc();

private:
    string name;
};

void testUniquePtr();
void testSharePtr();
void testWeakPtr();

int main()
{
    testUniquePtr();
    system("pause");

    testSharePtr();
    cout << "spc1 已经过期" <<endl;
    system("pause");

    testWeakPtr();
    system("pause");
}

void testSharePtr()
{
    cout << "测试share智能指针" << endl;
    shared_ptr<poco_one> spc1(new poco_one("lily"));
    cout << "当前引用计数为 : " << spc1.use_count() <<endl;
    function<void(void)> func = [&]()
    {
        shared_ptr<poco_one> spc2 = spc1;
        cout << "当前引用计数为 : " << spc1.use_count() << endl;
        cout << "spc2 即将过期" <<endl;
    };

    func();
    cout << "当前引用计数为 : " << spc1.use_count() <<endl;
    cout << "spc2已过期"<<endl;
}
void testWeakPtr()
{
    cout << "测试weak智能指针" << endl;
    shared_ptr<poco_one> spc1(new poco_one("blaze"));
    cout << "当前引用计数为 : " << spc1.use_count() << endl;
    shared_ptr<poco_one> spc2 = spc1;
    cout << "当前引用计数为 : " << spc1.use_count() << endl;

    weak_ptr<poco_one> wpc = spc2;
    cout << "当前引用计数为 : " << spc1.use_count() << endl;

    wpc.lock()->showDesc();
}

void testUniquePtr()
{
    cout << "测试unique智能指针"<<endl;
    unique_ptr<poco_one> pcone1(new poco_one("rock"));
    //unique_ptr<poco_one> pcone2 = pcone1;  //无效 不可复制
    pcone1->showDesc();
    unique_ptr<poco_one> pcone3 = std::move(pcone1);
    pcone1->showDesc();
    pcone3->showDesc();
    pcone3.reset();
    pcone3->showDesc();
    pcone1.reset();  //已经无效

    unique_ptr<poco_one> pcone4;
    pcone4->showDesc();

}

poco_one::poco_one(string n)
{
    cout << "poco_one 对象已经被初始化" << endl;
    name = n;
}

poco_one::~poco_one()
{
    cout << "poco_one 对象即将被销毁" << endl;;
}

void poco_one::showDesc()
{
    if (&name == NULL)
    {
        cout << "本对象已经被干掉或者不存在" << endl;
        return;
    }
    cout << name + ":show something"<< endl;
}

其执行结果为:

测试unique智能指针
poco_one 对象已经被初始化
rock:show something
本对象已经被干掉或者不存在
rock:show something
poco_one 对象即将被销毁
本对象已经被干掉或者不存在
本对象已经被干掉或者不存在
请按任意键继续. . .
测试share智能指针
poco_one 对象已经被初始化
当前引用计数为 :
当前引用计数为 :
spc2 即将过期
当前引用计数为 :
spc2已过期
poco_one 对象即将被销毁
spc1 已经过期
请按任意键继续. . .
测试weak智能指针
poco_one 对象已经被初始化
当前引用计数为 :
当前引用计数为 :
当前引用计数为 :
blaze:show something
poco_one 对象即将被销毁
请按任意键继续. . .

注:

C++类的成员方法即便不实例化对象也可以调用,同时智能指针也可以调用。但是如果动态成员变量没有初始值的话就会很危险!

lambda表达式如果用[=]复制的方式传参,那么这个复制出来的值要在lambda表达式所在的方法结束后才会过期,而不是lambda方法本身结束后过期。

C++11 智能指针的更多相关文章

  1. c++11 智能指针 unique_ptr、shared_ptr与weak_ptr

    c++11 智能指针 unique_ptr.shared_ptr与weak_ptr C++11中有unique_ptr.shared_ptr与weak_ptr等智能指针(smart pointer), ...

  2. C++11——智能指针

    1. 介绍 一般一个程序在内存中可以大体划分为三部分——静态内存(局部的static对象.类static数据成员以及所有定义在函数或者类之外的变量).栈内存(保存和定义在函数或者类内部的变量)和动态内 ...

  3. C++11智能指针之std::unique_ptr

    C++11智能指针之std::unique_ptr   uniqut_ptr是一种对资源具有排他性拥有权的智能指针,即一个对象资源只能同时被一个unique_ptr指向. 一.初始化方式 通过new云 ...

  4. 【C++11新特性】 C++11智能指针之weak_ptr

    如题,我们今天要讲的是C++11引入的三种智能指针中的最后一个:weak_ptr.在学习weak_ptr之前最好对shared_ptr有所了解.如果你还不知道shared_ptr是何物,可以看看我的另 ...

  5. 详解C++11智能指针

    前言 C++里面的四个智能指针: auto_ptr, unique_ptr,shared_ptr, weak_ptr 其中后三个是C++11支持,并且第一个已经被C++11弃用. C++11智能指针介 ...

  6. C++11智能指针

    今晚跟同学谈了一下智能指针,突然想要看一下C++11的智能指针的实现,因此下了这篇博文. 以下代码出自于VS2012 <memory> template<class _Ty> ...

  7. C++11智能指针的深度理解

    平时习惯使用cocos2d-x的Ref内存模式,回过头来在控制台项目中觉得c++的智能指针有点生疏,于是便重温一下.首先有请c++智能指针们登场: std::auto_ptr.std::unique_ ...

  8. C++11智能指针 share_ptr,unique_ptr,weak_ptr用法

    0x01  智能指针简介  所谓智能指针(smart pointer)就是智能/自动化的管理指针所指向的动态资源的释放.它是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动 ...

  9. C++11智能指针原理和实现

    一.智能指针起因 在C++中,动态内存的管理是由程序员自己申请和释放的,用一对运算符完成:new和delete. new:在动态内存中为对象分配一块空间并返回一个指向该对象的指针: delete:指向 ...

随机推荐

  1. hadoop 安装教程 转载

    hadoop2.2安装教程:http://www.aboutyun.com/thread-7684-1-1.html hadoop2.X使用手册1:通过web端口查看主节点.slave1节点及集群运行 ...

  2. Selenium-xpath详解

    1.XPATH是什么 XPATH是一门在XML文档中查找信息的语言,XPATH可用来在XML文档中对元素和属性进行遍历,主流的浏览器都支持XPATH,因为HTML页面在DOM中表示为XHTML文档.X ...

  3. [已解决] 快速理解RSA算法

    RSA算法基础详解 http://www.cnblogs.com/hykun/p/RSA.html RSA算法原理(一) http://www.ruanyifeng.com/blog/2013/06/ ...

  4. Thinkphp学习回顾(一)之基本结构目录

    TP框架的学习一般都是从了解框架的基本结构开始的,每个文件都有其专属的作用,我的TP框架的回顾也从基本结构开始讲起. 一.ThinkPHP的获取 http://www.thinkphp.cn   这是 ...

  5. java static静态方法的并发性

    在做一个web项目的时候需要做一个通用类去处理一些问题,想到这个类很多地方都有用到,又不想每次都new一个,因此就定义了里面的方法是静态方法,然后又因为多个静态方法都用到了同一个对象,结果定义了一个类 ...

  6. U盘插入电脑后,提示需要格式化U盘如何解决?

    未弹出U盘就拔掉U盘,有可能会破坏U盘的分区表.当再次把U盘插入电脑时,会提示需要格式化U盘,这是什么情况,如何解决呢?其实只要用DiskGenius硬盘恢复软件就可以解决这个问题.下面和小编一起来看 ...

  7. ACM 杭电HDU 2084 数塔 [解题报告]

    数塔 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submissi ...

  8. 企业办公3D指纹考勤系统解决方案(一)

    员工准时.正常出勤是企业考勤制度的基本要求,然而目前签名式.卡钟式.IC卡考勤系统均存在代打卡.人情卡.不易统计等漏洞,而市面上的光学指纹考勤机存在识别能力差.识别速度慢.使用寿命短.不能完全杜绝指纹 ...

  9. c++并发练习---生产者消费者模型

    问题:有一个生产者,多个消费者,生产者每生产一个,放入队列,多个消费者顺序从队列中取出数据,打印最终结果. 分析:首先这题,我本意应该设计成如下模型:生产者单开一个线程,向队列中放入数据,而消费者在锁 ...

  10. Top命令 -转

    Windows下的任务管理器虽然不好用(个人更喜欢Process Explorer些),但也算方便,可以方便的查看进程,CPU,内存...也可以很容易的结束进程 没有图形化界面下的Linux,也有命令 ...