智能指针

智能指针在C++11版本之后提供,包含在头文件中,包括三种:

  • shared_ptr
  • unique_ptr
  • weak_ptr

智能指针的作用

由于C++没有垃圾回收机制,一切内存堆操作都是程序员自己管理,但对于程序员来说管理堆不胜麻烦,稍有不慎忘记释放就会造成内存泄露最终导致内存溢出等问题。 而智能指针则能有效避免此类问题发生。

智能指针通过对普通指针进行类封装,使其表现的跟普通指针类似的行为。

shared_ptr指针

shared_ptr 使用引用计数,每一个shared_ptr的拷贝都指向相同的内存地址,每使用一次,内部的引用计数加1, 每析构一次,内部的引用计数减1,减到0时,自动删除所指向的堆内存。shared_ptr内部的引用计数是线程安全的,但是对象的读取需要加锁。

  • 初始化。std::shared_ptr n,也可以make_shared函数初始化。不能直接赋值一个指针,因为它是类。
  • 拷贝和赋值,拷贝引用计数加1,赋值引用计数减1,当计数为0时,自动释放内存。
  • get函数获取原始指针
  • 不要用一个原始指针初始化多个shared_ptr,否则会造成二次释放同一内存。
  • 避免循环引用,循环引用会导致内存泄漏。

unique_ptr指针

unique_ptr 唯一拥有其所指对象,统一时刻只能有一个unique_ptr指向给定对象(通过禁止拷贝语义,只有移动语义实现)。 相比原始指针,unique_ptr的RAII特性,使得其在出现异常时,能自动释放指向对象占用资源。unique_ptr生命周期从创建到作用域结束, 离开作用域时,若其指向对象,则将其所指向对象销毁。

unique_ptr在生命周期内,可以改变智能指针所指对象,通过release释放所有权,通过reset函数指定新对象,通过移动语义转移所有权。

weak_ptr指针

  • weak_ptr作为一个辅助智能指针,配合shared_ptr可以对资源使用情况进行观测。
  • weak_ptr可以从一个shared_ptr或另一个weak_ptr对象中构造,以获得资源观测权,它不会使原对象引用计数增加,

智能指针的原理

智能指针:实际指行为类似于指针的类对象,是利用了一种叫做RAII(资源获取即初始化)的技术对普通的指针进行封装, 它的一种通用实现方法是采用引用计数的方法。

  • 1.智能指针将一个计数器与类指向的对象相关联,引用计数跟踪共有多少个类对象共享同一指针。
  • 2.每次创建类的新对象时,初始化指针并将引用计数置为1;
  • 3.当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;
  • 4.对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;这是因为左侧的指针指向了右侧指针所指向的对象,因此右指针所指向的对象的引用计数+1;
  • 5.调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。
  • 6.实现智能指针有两种经典策略:一是引入辅助类,二是使用句柄类。这里主要讲一下引入辅助类的方法