智能指针 订阅
当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝;另一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享。智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象。 展开全文
当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝;另一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享。智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象。
信息
工作机制
类似C++的内置指针
外文名
smart pointer
经典策略
引入辅助类、使用句柄类
含    义
存储指向动态分配对象指针的类
中文名
智能指针
智能指针原理
每次创建类的新对象时,初始化指针并将引用计数置为1;当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,析构函数减少引用计数(如果引用计数减至0,则删除基础对象)。实现引用计数有两种经典策略:一是引入辅助类,二是使用句柄类。下面分别介绍这些内容
收起全文
精华内容
下载资源
问答
  • 智能指针

    多人点赞 2019-09-18 22:53:07
    为什么会出现智能指针智能指针是用来智能的管理指针指向的动态资源的释放。由于C++中没有内存的自动回收机制,因此,每次new出来的空间都需要delete,但是有些情况下,总是无法及时的delete,或者由于异常导致...

    为什么会出现智能指针:

    智能指针是用来智能的管理指针指向的动态资源的释放。由于C++中没有内存的自动回收机制,因此,每次new出来的空间都需要delete,但是有些情况下,总是无法及时的delete,或者由于异常导致程序提早退出,造成内存泄露,因此为了解决内存泄露的问题,产生了智能指针。智能指针是将对内存的管理交付给对象,因此当对象析构时就能够清理资源,有效的避免内存泄露问题。


    智能指针的种类:auto_ptr, unique_ptr, shared_ptr, shared_ptr。


    auto_ptr:

    实际上利用的是管理权限的转移,通过赋值运算符重载或者拷贝构造时,把p1置空,即将p1开辟的空间的管理权限交付给p2后,当我们再去访问旧指针时候,就会出错。因此此设计本身带有缺陷,建议什么情况下都不要使用。


    unique_ptr:

    为了解决auto_ptr转移管理权带来的弊端,因此使用了unique_ptr,unique_ptr一个对象只能指向一块给定的内存,也就是不支持拷贝和赋值。防止拷贝,可以解决atuo_ptr的问题。
    做法:1.把拷贝构造和赋值运算符的操作只声明,不定义。
    2.为了防止定义,在将声明私有。


    shared_ptr:

    核心思想: 引入了计数,使得多个指针可以指向同一块空间,当最后一个指针释放时才真正的释放这块空间。
    但是存在弊端:循环引用的问题。
    循环引用:
    举个例子:
    比如一个双向链表,定义了两个块空间,Node1,Node2。两个指针sp1,sp2。 sp1和sp2->prev都指向Node1,所以sp1的引用计数为2,同理,sp1->next 和sp2都指向Node2,所以sp2的引用计数也是2。
    当我们想要销毁某一个节点的时候,需要先将引用计数置为1,假如我们delete sp2这块空间,我们就需要将sp2的引用计数置为1,就是说我们需要将sp1->next这个指针销毁掉。把sp2->next销毁,就意味着先把sp1销毁。如果想把sp1销毁,就要把sp1的引用计数置为1,所以,我们就要把sp2->prev销毁,要想把sp2->prev销毁,就代表先要把sp2销毁,这样一来就陷入了无限循环中。

    在shared_ptr中,只有当引用计数减减之后等于0,析构时才会释放对象,但是如果析构对象时先析构sp2,但是由于sp2的空间sp1还在使用,所以使用sp2.use_count减减之后为1,不释放。sp1也是同样的道理,由于sp1空间sp2还在使用中,所以sp1.use_count减减之后,也不释放。sp1等着sp2先释放,sp2等着sp1先释放,二者互不相让,引用计数无法达到0,因此无法释放堆上的资源导致最终都没有释放成功,造成内存泄露。

    解决循环引用的方法:
    使用弱指针-------weak_ptr------,weak_ptr不增加引用计数。weak_ptr不能算是智能指针,因为它没有重载->和*,可以将weak_ptr理解成是一个shared_ptr的辅助工具,weak_ptr是shared_ptr的一个观察者,他只对shared_ptr进行了引用,而没有改变shared_ptr的引用计数,当weak_ptr看到shared_ptr失效后,weak_ptr也会相应失效。


    4种智能指针的应用场景:

    1.拒绝使用auto_ptr(管理单个堆对象)
    2.在确定无需对象共享的情况下,使用unique_ptr,管理单个堆对象
    3.在对象被共享的情况下,使用shared_ptr
    4.在需要访问shared_ptr对象,又不想改变其引用计数的时候(就是为了防止循环引用),使用weak_ptr;

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,298
精华内容 7,319
关键字:

智能指针