c++11为什么要引入这个东西?它的作用与好处是什么?
其实:目的是为了帮助我们管理内存生命周期,也就是帮助我们进行内存管理,自动释放!
也就是类似其它高级语言的垃圾回收机制(GC),但又不是真正的GC功能!
shared_ptr智能指针底层是采用引用计数的方式实现的。这么理解,智能指针在申请堆内存空间的同时,会为其配备一个整形值(初始值为 1),每当有新对象使用此堆内存时,该整形值 +1;反之,每当使用此堆内存的对象被释放时,该整形值减 1。当堆空间对应的整形值为 0 时,即表明不再有对象使用它,该堆空间就会被释放掉!
以下是引用shared_ptr智能指针底层源码的引用记数
public: _Sp_counted_base() noexcept : _M_use_count(1), _M_weak_count(1) { } virtual ~_Sp_counted_base() noexcept { }1、shared_ptr智能指针的创建
shared_ptr<T> 类模板中,提供了多种实用的构造函数,这里列举了几个常用的构造函数(以构建指向 int 类型数据的智能指针为例)。 1) 构造 shared_ptr<T> 类型的空智能指针:
std::shared_ptr<int> p1; //不传入任何实参 std::shared_ptr<int> p2(nullptr); //传入空指针 nullptr有一点要说明一下: 声明这个p1/p2时,它的引用记数是0,不是1哈! 在构建 shared_ptr 智能指针,也可以明确其指向。例如:
std::shared_ptr<int> pint(new int(10));构建了一个 shared_ptr 智能指针,其指向一块存有 10 这个 int 类型数据的堆内存空间。 C++11 标准中还提供了 std::make_shared<T> 模板函数,其可以用于初始化 shared_ptr 智能指针,例如:
std::shared_ptr<int> pmake = std::make_shared<int>(10);3) 除此之外,shared_ptr<T> 模板还提供有相应的拷贝构造函数和移动构造函数,例如:
//调用拷贝构造函数 std::shared_ptr<int> p4(p3);//或者 std::shared_ptr<int> p4 = p3; //调用移动构造函数 std::shared_ptr<int> p5(std::move(p4)); //或者 std::shared_ptr<int> p5 = std::move(p4);excample:
// shared_ptr constructor example #include <iostream> #include <memory> struct C {int* data;}; int main () { std::shared_ptr<int> p1; std::shared_ptr<int> p2 (nullptr); std::shared_ptr<int> p3 (new int); std::shared_ptr<int> p4 (new int, std::default_delete<int>()); std::shared_ptr<int> p5 (new int, [](int* p){delete p;}, std::allocator<int>()); std::shared_ptr<int> p6 (p5); std::shared_ptr<int> p7 (std::move(p6)); std::shared_ptr<int> p8 (std::unique_ptr<int>(new int)); std::shared_ptr<C> obj (new C); std::shared_ptr<int> p9 (obj, obj->data); std::cout << "use_count:\n"; std::cout << "p1: " << p1.use_count() << '\n'; std::cout << "p2: " << p2.use_count() << '\n'; std::cout << "p3: " << p3.use_count() << '\n'; std::cout << "p4: " << p4.use_count() << '\n'; std::cout << "p5: " << p5.use_count() << '\n'; std::cout << "p6: " << p6.use_count() << '\n'; std::cout << "p7: " << p7.use_count() << '\n'; std::cout << "p8: " << p8.use_count() << '\n'; std::cout << "p9: " << p9.use_count() << '\n'; return 0; }输出:
use_count: p1: 0 p2: 0 p3: 1 p4: 1 p5: 2 p6: 0 p7: 2 p8: 1 p9: 2在某些场景中,自定义释放规则是很有必要的。比如,对于申请的动态数组来说,shared_ptr 指针默认的释放规则是不支持释放数组的,只能自定义对应的释放规则,才能正确地释放申请的堆内存。 对于申请的动态数组,释放规则可以使用 C++11 标准中提供的 default_delete<T> 模板类,我们也可以自定义释放规则:
以下引用别的文档的分享:
2、shared_ptr<T>模板类提供的成员方法
为了方便用户使用 shared_ptr 智能指针,shared_ptr<T> 模板类还提供有一些实用的成员方法,它们各自的功能如表 1 所示。
表 1 shared_ptr<T>模板类常用成员方法 成员方法名功 能operator=()重载赋值号,使得同一类型的 shared_ptr 智能指针可以相互赋值。operator*()重载 * 号,获取当前 shared_ptr 智能指针对象指向的数据。operator->()重载 -> 号,当智能指针指向的数据类型为自定义的结构体时,通过 -> 运算符可以获取其内部的指定成员。swap()交换 2 个相同类型 shared_ptr 智能指针的内容。reset()当函数没有实参时,该函数会使当前 shared_ptr 所指堆内存的引用计数减 1,同时将当前对象重置为一个空指针;当为函数传递一个新申请的堆内存时,则调用该函数的 shared_ptr 对象会获得该存储空间的所有权,并且引用计数的初始值为 1。get()获得 shared_ptr 对象内部包含的普通指针。use_count()返回同当前 shared_ptr 对象(包括它)指向相同的所有 shared_ptr 对象的数量。unique()判断当前 shared_ptr 对象指向的堆内存,是否不再有其它 shared_ptr 对象再指向它。operator bool()判断当前 shared_ptr 对象是否为空智能指针,如果是空指针,返回 false;反之,返回 true。除此之外,C++11 标准还支持同一类型的 shared_ptr 对象,或者 shared_ptr 和 nullptr 之间,进行 ==,!=,<,<=,>,>= 运算。
官方链接详细介绍:http://www.cplusplus.com/reference/memory/shared_ptr/
总结: shared_ptr并不是真正的线程安全的,当然你要用到这么深入的时候再去查资料研究吧!
keivin2006 认证博客专家 C/C vc/qt 音视频 一名c/c++/vc/qt 的小学生,“精通”c,“精通”c++,“精通”vc++,“精通”php,“精通”qt,“精通”java,“精通”python,“精通”c#,“精通”...! 编不下去了,只要见过名字的都我“精通”....为哈,因为我现在是csdn“砖家”了!本人qq: 88520350 qq学习群:930432714 (C/C++/QT/VC学习交流群) 海量学习资料都分享在群里指点学习方向,掌握学习要点,快速提高技术水平, 技术分享,共同学习!