【C++11新特性】详解智能指针 创建、使用、注意事项

创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c++系列专栏:C/C++零基础到精通 🔥

给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ

在这里插入图片描述

c语言内容💖:

专栏:c语言之路重点知识整合

【c语言】全部知识点总结



C++11 中引入了智能指针,便于进行内存管理

使用智能指针 需要包含头文件: #include <memory> 以及 std 命名空间

智能指针会自动回收空间,不需要担心内存泄漏问题


四种智能指针:

  • auto_ptr(C++11 被弃用)
  • unique_ptr
  • shared_ptr
  • weak_ptr

一、 auto_ptr

创建auto_ptr对象的三种方式:

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

class A
{
public:
    void fun()
    {
        cout << this << "A::fun()" << endl;
    }
};

int main()
{
    auto_ptr<A> p1(new A() );
    
    auto_ptr<A> p2;
    p2.reset(new A()); 
    
    auto_ptr<A> p3;
    p3 = p1;	//把p1空间的归属权交给p3,后面不能再用p1

    return 0;
}

使用对象:

p3.get()->fun();

p3->fun();

auto_ptr 存在的问题:将 p1 赋值给 p3 ,会将 p1 的资源转交给 p3,而不是复制,此时再调用 p1会出现空指针问题:

auto_ptr<A> p3;
p3 = p1;	
p1->fun();	//error

因此在 C++11 中被弃用。

二、unique_ptr

唯一所属权的智能指针,只能有一个指针管理内存

三种创建对象与使用方式:

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

class A
{
public:
    void fun()
    {
        cout << this << "A::fun()" << endl;
    }
};

int main()
{
    //1.
    unique_ptr<A> p1(new A());
    p1->fun();

    //2.reset
    unique_ptr<A> p2;
    p2.reset(new A());
    p2.get()->fun();
    
    //3.move
    unique_ptr<A> p3;
    p3 = std::move(p2);	//使用权传递,不可以直接使用 = 赋值
    (*p3).fun();
    cout << p2.get() << endl;
    // 4.make_unqiue
    unique_ptr<A> p4 = make_unique<A>();    //c++14引入
    return 0;
}

image.png

C++11中unique_ptr 用于替代废弃的auto_ptr

空间使用权传递的方式要求更严格:不可以直接使用 = 赋值,可以使用 std::move 将左值转为右值进行赋值

同时,当一个unique_ptr的使用权被交出后或者超出智能指针的作用域后,这个指针会自动失效

image.png

但是 unique_ptr 一个只能指向一块空间,如果 reset 转移到另一块空间,原先的内存就无法指向使用了,因此引入了 shared_ptr:

三、shared_ptr

共享所属权的智能指针

多个指针可以指向同一个空间,可以同时生效

使用引用计数管理回收 ,使用 use_count函数可以查看指向这块空间的指针数量

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

class A
{
public:
    void fun()
    {
        cout << "A::fun()" << endl;
    }
    ~A()
    {
        cout << "A::~A()" << endl;
    }
};

int main()
{
    shared_ptr<A> p1(new A());
    p1->fun();

    shared_ptr<A> p2;
    p2.reset(new A());
    (*p2).fun();

    shared_ptr<A> p3;
    p3 = make_shared<A>();
    p3.get()->fun();

    {
        shared_ptr<A> p4;
        p4 = p3; // 指向同一块空间 两个指针共享内存
        cout << p4.use_count() << endl;
        cout << "p3: " << p3.get() << " p4: " << p4.get() << endl;
    } // p4在此回收
    
    return 0;
}

image.png

shared_ptr 存在循环引用的问题:

如果两个 shared_ptr 相互引用,引用计数永远不会变为0,因此它们所指向的对象也不会被删除,这会导致内存泄漏

例如:

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

class B;
class A
{
public:
    shared_ptr<B> pb;
    void fun()
    {
        cout << "A::fun()" << endl;
    }
    ~A()
    {
        cout << "A::~A()" << endl;
    }
};

class B
{
public:
    shared_ptr<A> pa;
    void fun()
    {
        cout << "B::fun()" << endl;
    }
    ~B()
    {
        cout << "B::~B()" << endl;
    }
};

int main()
{
    shared_ptr<A> pa = make_shared<A>();
    shared_ptr<B> pb = make_shared<B>();
    pa->pb = pb;
    pb->pa = pa;
    pb->fun();
    pa->fun();
    // pa和 pb 的引用计数都是 1,但由于它们相互引用,它们都不会被删除

    return 0;
}

image.png
为了解决循环引用的问题,引入了 weak_ptr

四、weak_ptr

用于解决shared_ptr存在循环引用的问题

弱引用计数的共享使用权的智能指针,不能独立存在,配合shared_ptr使用

如果使用 weak_ptrshared_ptr指向同一空间,引用计数不会加1

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

class B;
class A;

class A
{
public:
    shared_ptr<B> pb;
    void fun()
    {
        cout << "A::fun()" << endl;
    }
    ~A()
    {
        cout << "A::~A()" << endl;
    }
};

class B
{
public:
    weak_ptr<A> pa; //使用weak_ptr
    void fun()
    {
        cout << "B::fun()" << endl;
    }
    ~B()
    {
        cout << "B::~B()" << endl;
    }
};

int main()
{
    shared_ptr<A> pa = make_shared<A>();
    shared_ptr<B> pb = make_shared<B>();
    pa->pb = pb;
    pb->pa = pa;
    pb->fun();
    pa->fun();
    return 0;
}

image.png

weak_ptr 注意事项

  • 避免悬空指针 使用 weak_ptr 之前,必须确保其所指向的对象仍然存在
  • std::weak_ptr 应该通过 shared_ptr 构造而来,不可直接从裸露指针构造
  • 注意失效 当最后一个 shared_ptr 所引用的对象被释放时,weak_ptr 会自动失效

在这里插入图片描述

大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天喜Studio

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值