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. 你年纪轻轻怎么这么"不讲理"

    今天在公交上遇到一出"精彩的打戏",这给我的12月份带来了一丝的"惊喜",1号就能让我碰到这样的事,看来这个月会惊喜不断啊!!!! 这精彩的戏是这样的,公交到了 ...

  2. NOIP2014 day2 T2寻找道路

    #include<iostream> #include<cmath> #include<cstdlib> #include<cstdio> #inclu ...

  3. Topcoder SRM 683 Div2 B

    贪心的题,从左向右推过去即可 #include <vector> #include <list> #include <map> #include <set&g ...

  4. Vim升华之树形目录插件NERDTree安装图解

    来源:CSDN 作者:mybelief321 无意中看到实验室的朋友使用的vim竟然能在左边显示树形目录,感觉很方便,这样子文件夹有什么文件一目了然.他说是一个插件叫NERDTree,安装执行后的效果 ...

  5. [转]VB Winsock 控件TCP与UDP连接实例

    [-] 可能的用途 选择通讯协议 协议的设置 确定计算机的名称 TCP 连接初步 接受多个连接请求 UDP 初步 关于 Bind 方法   利用 WinSock 控件可以与远程计算机建立连接,并通过用 ...

  6. [Python]实现简单决策树

    基本思路: 通过香农熵来决定每一层使用哪一种标签做分类,分类后,通过多数表决法来决定该层两个节点的类别.每次消耗一个标签,所以一共需要递归"标签个数"层. # -*- coding ...

  7. 关于tomcat访问managerapp出现403报错的解决方法

    最近工作需要在tomct下部署war包并访问. 学了几种方法后想从Tomcat Web Application Manager去部署. 但是启动tomcat后浏览器http://localhost:8 ...

  8. 如何为数据源向导填加一种自定义的数据源类型(win示例)

    https://www.devexpress.com/Support/Center/Example/Details/T310160

  9. LINQ之路 9:LINQ to SQL 和 Entity Framework(上)

    在上一篇中,我们从理论和概念上详细的了解了LINQ的第二种架构“解释查询”.在这接下来的二个篇章中,我们将使用LINQ to SQL和Entity Framework来实践“解释查询”,学习这些技术的 ...

  10. python走起之第十四话

    HTML 标题 HTML 标题(Heading)是通过<h1> - <h6> 标签来定义的. 实例 <h1>这是一个标题</h1> <h2> ...