美文网首页
C++11智能指针

C++11智能指针

作者: Tomtoms | 来源:发表于2019-11-07 23:05 被阅读0次

[C++11]智能指针

C++11包括了三种智能指针:

  1. shared_ptr
  2. weak_ptr
  3. unique_ptr

shared_ptr

shared_ptr是一个包装类,内部包装了真正的数据指针以及引用计数,当引用计数为0时自动释放指针,跟指针一样,重载了->操作符,也可以用*来进行解引用。
简单介绍

#include <iostream>
#include <memory>
using namespace std;


int main(int /argc/, char const */argv/[])
{
    int *p = new int(2);

    /// 智能指针初始化/
    shared_ptr<int> sp1(p);

    /// 不能构造指向相同数据的智能指针,否则p会被释放两次/
    /// shared_ptr<int> sp2(p);/

    shared_ptr<int> sp2 = sp1;
    shared_ptr<int> sp3 = sp1;
    /// 三者的引用计数均为3/
    cout << sp1.use_count() << endl;
    cout << sp2.use_count() << endl;
    cout << sp3.use_count() << endl;

    /// 不声明指针的智能指针构造方法/
    shared_ptr<int> sp4 = make_shared<int>(2);
    shared_ptr<int> sp5 = sp4;

    /// 引用计数为2/
    cout << sp4.use_count() << endl;
    cout << sp5.use_count() << endl;

    /// 重置sp4,引用计数变为1/
    sp4.reset();
    cout << sp4.use_count() << endl; /// 0/
    cout << sp5.use_count() << endl; /// 1/

    /// 重置sp4,sp4和sp5指向不同的数据/
    sp4.reset(new int(3));
    cout << sp4.use_count() << endl; /// 1/
    cout << sp5.use_count() << endl; /// 1/

    /// 判断智能指针是否为空/解引用智能指针/
    shared_ptr<int> sp;
    if(!sp){
        cout << "sp is null" << endl;
    }
    sp.reset(new int(5));
    if(sp){
        cout << "sp is " << *sp << endl;
    }
    return 0;
}

shared_ptr构造类对象的智能指针

#include <iostream>
#include <memory>
using namespace std;

class Foo{
    public:
    Foo(int /i/, int /j/){
        this->i = i;
        this->j = j;
    }
    void print(){cout << i << j << endl;}
    ~Foo(){
        cout << "destruct" << endl;
    }

    private:
    int i;
    int j;
};

int main(int /argc/, char const */argv/[])
{
    shared_ptr<Foo> foo = make_shared<Foo>(2,3);
    shared_ptr<Foo> foo2 = foo;
    shared_ptr<Foo> foo3 = foo2;
    cout << foo.use_count() << endl; /// 3/

    Foo* foo4 = foo.get(); /// 不会改变引用的计数/
    cout << foo.use_count() << endl; /// 3/
    foo4->print();

    foo2.reset();
    foo3.reset();
    foo.reset(); /// 调用析构/
    /// 如果注释掉foo的重置,析构函数会发生在打印“end of main"以后/
    cout << "End of main" << endl;
    return 0;
}

weak_ptr

简单来说,weak_ptr就是不能增加引用计数的智能指针,也没有重载*和->等符号的智能指针,但是weak_ptr::use_count()可以查看引用计数,也可以通过weak_ptr::expired查看是否过期。

#include <iostream>
#include <memory>
using namespace std;

int main(int /argc/, char const */argv/[])
{
    weak_ptr<int> wp0;
    cout << "wp0.expired() == " << std::boolalpha << wp0.expired() << endl; /// true/

    shared_ptr<int> sp1(new int(5));
    weak_ptr<int> wp1(sp1);
    cout << "wp1.expired() == " << std::boolalpha << wp1.expired() << endl; /// false/
    cout << "use count " << wp1.use_count() << endl; /// 1/
    return 0;
}

同时,weak_ptr还能通过lock方法来获取一个shared_ptr智能指针,在获取shared_ptr智能指针的时候会提升智能指针的引用计数

      shared_ptr<int> sp2(new int(4));
    weak_ptr<int> wp2(sp2);
    cout << "wp2.expired() == " << std::boolalpha << wp2.expired() << endl; /// false/
    cout << "use count " << wp2.use_count() << endl; /// 1/

    cout << "*wp2.lock() == "
            << *wp2.lock() << endl; /// 4/

    cout << "use count " << wp2.use_count() << endl; /// 1/
    shared_ptr<int> sp3(wp2);
    shared_ptr<int> sp4(wp2);
    /// 智能指针可以初始化多个shared_ptr,而普通指针不可以/
    cout << "use count " << wp2.use_count() << endl; /// 3/

unique_ptr

顾名思义,unique_ptr只能有一个,不能复制,只能通过move实现转移内部指针。

unique_ptr<T>myPtr(newT);//ok
unique_ptr<T>otherPtr=myPtr;//编译错误

智能指针的应用场景

实现观察者模式

现在有一个设备模块,该模块从设备获取一条条数据(这里用Record表示一条数据),并通过观察者模式把Record分发给所有(观察了该数据的)观察者。观察者一般都是视图,如视图A得到数据后,通过表格显示数据的内容,而视图B上得到数据后,通过趋势图显示数据的内容。
当用户关闭了所有视图,意味没有视图再使用数据Record了,这时就可以释放掉Record;但是只要有一个视图在使用record,就不能释放Record。
如何管理Record的释放呢?这种情况使用智能指针,可以做到所有视图关闭后,自动释放Record。

工厂模式

假如你编写了一个工厂类,它提供一个接口,根据配置产生各种对象(内部调用new新建对象)。
由于该类很NewBee,它被封装为动态库提供给其他同事,当其他同事调用动态库得到新建对象后,新建对象将来由谁负责释放呢?如果没有统一且明确的沟通确认,很容易出现双方都忘记释放新建对象,或者同一个新建对象被双方都释放了一次的情况!
这时候你甩出了一个智能指针,然后宣布:大家都不用关心谁来释放了,让指针自己释放去吧。
::类对象应该让库释放还是让使用者释放一直很让人头疼::

避免代码发生异常时内存泄漏

void foo(){
        try{
            int *p = new int(0);
            do_something(p);
            delete p;
        }
        catch(...){
        }
    }

如果do_something函数中发生了异常,那么p就不会被释放,智能指针可以防止这种事情的发生

学习/c++

相关文章

  • C++11智能指针

    [C++11]智能指针 C++11包括了三种智能指针: shared_ptr weak_ptr unique_pt...

  • C++ 智能指针

    C++智能指针[https://zhuanlan.zhihu.com/p/54078587] C++11中智能指针...

  • 现代 C++:一文读懂智能指针

    智能指针 C++11 引入了 3 个智能指针类型: std::unique_ptr :独占资源所有权的指针。...

  • 智能指针和垃圾回收

    堆内存管理:智能指针与垃圾回收 显式内存管理 野指针 重复释放 内存泄漏 C++11 的智能指针 unique_p...

  • C++之智能指针

    本文主要总结C++11中的几种智能指针的原理,使用及实现方式。 I、上帝视角看智能指针 1、智能指针的引用是为了方...

  • Caffe 架构学习-底层数据1

    前言 shared_ptr智能指针 为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Point...

  • C++ 11 常用特性的使用经验总结(二)

    4、智能指针内存管理 在内存管理方面,C++11的std::auto_ptr基础上,移植了boost库中的智能指针...

  • 使用 C++11 智能指针时要避开的 10 大错误

    我很喜欢C++11的智能指针。在很多时候,对很多讨厌自己管理内存的人来说是天赐的礼物。在我看来,C++11的智能指...

  • std::unique_ptr使用

    1 引言 std::unique_ptr是c++11起引入的智能指针,为什么必须要在c++11起才有该特性,主要还...

  • 智能指针学习

    智能指针 介绍 为了更容易(同时也更安全的管)的使用动态内存,C++11提供了智能指针来管理new出来的内存sha...

网友评论

      本文标题:C++11智能指针

      本文链接:https://www.haomeiwen.com/subject/rmmbbctx.html