C++11的智能指针

Smart Pointers

  • 为了解决**内存泄漏(memory leak)**问题, C++11引入的新机制.
    • 使用完后, 这些指针会自动释放, 不需要程序员操作.
  • 一共有三个智能指针
    • std::unique_ptr - single ownership
    • std::shared_ptr - shared ownership
    • std::weak_ptr - temp / no ownership
    • defined in <memory> header

unique_ptr

在这里插入图片描述
在这里插入图片描述

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

void bar1(Person * p) {
    cout<<p->age<<endl;
//    delete p; 如果这里释放了, test01函数中p指针就成了一个野指针	
}

void bar2(unique_ptr<Person> p) {
    cout<<p->age<<endl;
}

void test01() {
    Person * p = new Person();
    bar1(p);
    if (p != NULL) {
        cout<<p->age<<endl;
    }
//    delete p;
}

void test02() {
    unique_ptr<Person> p = make_unique<Person>();
    bar2(move(p));
    if (p == NULL) {
        cout<<"NULL pointer"<<endl;
    }
    
}

int main() {
    test01();
    test02();
    return 0;
}

Person created
0
0
Person created
0
Person destroyed
NULL pointer
  • unique_ptr 指针指向的内存块只能有一个拥有者, 即只能有一个变量指向它. 使用move函数将所有权转移后, 原来的指针变量就变为NULL.

unique_ptr 构造

在这里插入图片描述

  • 不能把裸指针肤质给unique_ptr
  • unique_ptr<Node> p1 = make_unique<Node>();
  • 因为unique_ptr 是single ownership, 所以不能=(拷贝)赋值
  • auto p2 = move(p1);

examples

在这里插入图片描述

Life Cycle

在这里插入图片描述





shared_ptr

  • 有一个use_count 引用计数变量. 用来维护该对象被多少指针指向. 通过use_count()成员函数获得
  • 最常使用的, 和裸指针的用法相似, 只是这个可以被自动释放.

shared_ptr 构造

在这里插入图片描述

  • =赋值, use_count 会增加
  • move, use_count仍然不变, 原来的变为空指针

examples

在这里插入图片描述

  • 虽然有多个use_count, 但是对象始终只有一个, make_shared()时创建. 因此整个过程只有最后析构了一个对象.

Life Cycle

在这里插入图片描述





weak_ptr

在这里插入图片描述

  • 使用之前必须转换成shared_ptr, 使用的时候如果原来的shared_ptr还存在, 则正常使用. 否则就不能使用, 也不会报错.

examples

在这里插入图片描述

总结

  • 在多线程了,使用shared_ptr更新共享资源可能存在竞争条件, 还需要加锁.

使用智能指针写一个链表

  • unique_ptr 没有 = 赋值
  • 在单线程里 shared_ptr更像原生指针
  • get()函数, 获得对象里的原生指针 C++ 11 智能指针详解
#include <iostream>
#include <memory>
using namespace std;

template <typename T>
struct Node {
    T val;
//    unique_ptr<Node<T>> next;
    shared_ptr<Node<T>> next;
    Node(){
        cout<<"Node"<<val<<endl;
    }
    ~Node(){
        cout<<"~Node"<<val<<endl;
    }
};

template <typename T>
class Link {
public:
    // 头插法
    void creatLink(int val){
//        auto node = make_unique<Node<T>>();
        auto node = make_shared<Node<T>>();
        node->val = val;
        node->next = move(head.next);
        head.next = move(node);
    }
    void print() {
//        Node<int>* node = head.next.get(); // get()方法获得原生指针
//        auto node = move(head.next);   // 使用的是unique_ptr
        shared_ptr<Node<T>> node = head.next;
        while(node != NULL) {
            cout<<node->val<<endl;
            node = node->next;
        }
    }
    Node<T> head;
};

int main() {
    Link<int> lk;
    for (int val : {1,2,3,4,5}) {
        lk.creatLink(val);
    }
    lk.print();
    return 0;
}

智能指针原理实现

shellmad-17_C++新特性 智能指针的原理–bilibili

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值