C++Smart Pointer智能指针怎么用

发布时间:2022-03-14 13:32:49 作者:iii
来源:亿速云 阅读:302

这篇文章主要讲解了“C++Smart Pointer智能指针怎么用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++Smart Pointer智能指针怎么用”吧!

一、为啥使用智能指针呢

标准库中的智能指针:
std::auto_ptr    --single ownership  (C++98中出现,缺陷较多,被摒弃)
std::unique_ptr  --single ownership  (C++11替代std::auto_ptr,用于单线程)
std::shared_ptr  --shared ownership  (C++11,用于多线程)
std::weak_ptr    --temp/no ownership (C++11)
Introduced in C++ 11
Defined in <memory> header.

首先看一个下面的栗子,左边是木有使用智能指针的情况,当执行foo()函数,其中的e指针会在bar(e)时传入bar函数,但是在bar函数结束后没有人为delete e时,就会导致内存泄漏;但是在右边的栗子中,使用了unique_ptr智能指针(single ownership),就能防止内存泄漏。

C++Smart Pointer智能指针怎么用

智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。

注意:每一种智能指针都可以增加内存的引用计数。

shared_ptr进行初始化时不能将一个普通指针直接赋值给智能指针,因为一个是指针,一个是类。可以通过make_shared函数或者通过构造函数传入普通指针。并可以通过get函数获得普通指针。

#include <string>
#include <memory>
using namespace std;
class report
{
private:
    string str;
public:
    report(const string s):str(s) //构造方法
    {
        cout<<"1 report Object  has been build!"<<endl;
    }
    ~report()
    {
        cout<<"3 report Object  deleted!"<<endl;
    }
    void talk()
    {
        cout<<str<<endl;
    }
};
int main()
{
    string talk="2 hello,this is a test!";
    {
        auto_ptr<report> ptr(new report(talk));
        ptr->talk();
    }
    {
        shared_ptr<report> ptr(new report(talk));
        ptr->talk();
    }
    {
        unique_ptr<report> ptr(new report(talk));
        ptr->talk();
    }
    return 0;
}

C++Smart Pointer智能指针怎么用

二、shared_ptr智能指针

shared_ptr实现了共享拥有的概念,利用“引用计数”来控制堆上对象的生命周期。

share_ptr的生命周期:

C++Smart Pointer智能指针怎么用

原理:在初始化的时候引用计数设为1,每当被拷贝或者赋值的时候引用计数+1,析构的时候引用计数-1,直到引用计数被减到0,那么就可以delete掉对象的指针了。他的构造方式主要有以下三种:

shared_ptr<Object> ptr;
shared_ptr<Object> ptr(new Object);
shared_ptr<Object> ptr(new Object, [=](Object *){ //回收资源时调用的函数 });
auto ptr = make_shared<Object>(args);
auto ptr = make_shared<Object>(args);

上面第四种方法,使用标准库里边的make_shared<>()模板函数。该函数会调用模板类的构造方法,实例化一个堆上对象,然后将保存了该对象指针的shared_ptr返回。参数是该类构造函数的参数,所以使用make_shared<>()就好像单纯地在构造该类对象一样。auto是C++11的一个关键字,可以在编译期间自动推算变量的类型,在这里就是shared_ptr<Object>类型。

C++Smart Pointer智能指针怎么用

shared_ptr的其他成员函数:

use_count()	//返回引用计数的个数
unique()	//返回是否是独占所有权(use_count是否为1)
swap()		//交换两个shared_ptr对象(即交换所拥有的对象,引用计数也随之交换)
reset()		//放弃内部对象的所有权或拥有对象的变更, 会引起原有对象的引用计数的减少

三、unique_ptr智能指针

注意unique_ptr是single ownership的,不能拷贝。其构造方式如下:

C++Smart Pointer智能指针怎么用

unique_ptr的生命周期:

C++Smart Pointer智能指针怎么用

四、weak_ptr智能指针

C++Smart Pointer智能指针怎么用

五、智能指针怎么解决交叉引用,造成的内存泄漏

结论:创建对象时使用shared_ptr强智能指针指向,其余情况都使用weak_ptr弱智能指针指向。

5.1 交叉引用的栗子:

当A类中有一个指向B类的shared_ptr强类型智能指针,B类中也有一个指向A类的shared_ptr强类型智能指针。

main函数执行后有两个强智能指针指向了对象A,对象A的引用计数为2,B类也是:

#include <iostream>
#include <memory>
using namespace std;
class B;
class A{
public:
    shared_ptr<B> _bptr;
};
class B{
public:
    shared_ptr<A> _aptr;
};
int main(){
    shared_ptr<A> aptr(new A());
    shared_ptr<B> bptr(new B());
    aptr->_bptr = bptr;
    bptr->_aptr = aptr;
    return 0;
}

C++Smart Pointer智能指针怎么用

而当主函数mainreturn返回后,对象A的引用计数减一变为1(aptr没指向A对象了),B对象也是,引用计数不为0,即不能析构2个对象释放内存,造成内存泄漏。

5.2 解决方案

将类A和类B中的shared_ptr强智能指针都换成weak_ptr弱智能指针;

class A{
public:
    weak_ptr<B> _bptr;
};
class B{
public:
    weak_ptr<A> _aptr;
};

weak_ptr弱智能指针,虽然有引用计数,但实际上它并不增加计数,而是只观察对象的引用计数。所以此时对象A的引用计数只为1,对象B的引用计数也只为1。

C++Smart Pointer智能指针怎么用

六、智能指针的注意事项

shared_ptr<int> p = make_share<int> (42);
int *q = p.get();
{
  shared_ptr<int>(q); 
} // 程序块结束,q被销毁,指向的内存被释放。
int foo = *p; //  出错,p指向的内存已经被q释放,这是用get() 初始化另外的智能指针惹得祸。
// 请记住,永远不要用get初始化另外一个智能指针。

能使用unique_ptr时就不要使用share_ptr指针(后者需要保证线程安全,所以在赋值or销毁时overhead开销更高)。

感谢各位的阅读,以上就是“C++Smart Pointer智能指针怎么用”的内容了,经过本文的学习后,相信大家对C++Smart Pointer智能指针怎么用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

推荐阅读:
  1. c++智能指针怎么用
  2. pointer-events属性是什么?pointer-events属性详解

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++ smart

上一篇:feign参数过多导致调用失败怎么办

下一篇:mybatis怎么批量修改数据

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》