c++11智能指针
shared_ptr
- shared_ptr定义在memory头文件中,位于std命名空间内,shared_ptr的底层是采用引用计数实现的 -> 智能指针在申请内存空间时,会为其配置一个整型(初始值为1),每当有新对象使用次空间时,该整形值+1,反之,每当使用此空间的对象被释放时,该整型值-1。当堆空间对应的整型值为0时,表示不会有对象使用该空间了,该堆空间就会被释放
创建shared_ptr
-
- 构建shared_ptr类型的空智能指针
shared_ptr<int> p1(nullptr); //传入空指针 shared_ptr<int> p2; //不传任何实参
注:这种初始化的引用计数是0而不是1,因为没有堆空间的开辟
-
- 在构建智能指针时明确其指向
shared_ptr<int> p3(new int(10)); shared_ptr<int> p3 = std::make_shared<int>(10);
-
- 通过拷贝构造和移动构造创建智能指针
//调用拷贝构造函数 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);
注:这里调用拷贝构造和移动构造的结果是不一样的
调用拷贝构造-> p3和p4指向同一块空间,这块堆空间的引用计数+1。
调用移动构造-> p5指向原来p4指向的空间(引用计数为1),p4变成空智能指针
shared_ptr成员函数
shared_ptr还提供了一些类成员函数,其中get()可以获得shared_ptr所包含的原生指针,reset如果没有实参,会将当前调用对象的对内存引用计数-1,同时将当前对象置为空指针,如果有对象,将当前shared_ptr指向参数,并将原始空间的智能指针-1,use_count()获得当前shared_ptr的引用计数, operator*()可以获得当前指针指向的数据, 其余函数请参考官方文档了解详情
unique_ptr
-
unique_ptr也具有在适当时间自动释放堆内存空间的能力,但是和shared_ptr不同的是,unique_ptr指针指向的堆内存空间无法与其他的unique_ptr共享,也就是说,每个unique_ptr指针都独自拥有对其所指堆空间的所有权。
这就意味着,每个unique_ptr指针指向的堆内存空间的引用计数都只能是1,一旦unique_ptr指针放弃所指堆空间的所有权,该空间会立刻释放回收
创建unique_ptr
-
构造函数
//无明确指向 std::unique_ptr<int> p1(); std::unique_ptr<int> p2(nullptr); ///有明确指向 std::unique_ptr<int> p3(new int);
- 与shared_ptr不同unique_ptr没有make_shared()之类的函数
- 由于unique_ptr类型指针能共享使用堆内存空间, 因此unique_ptr没有拷贝构造函数,只有提供了移动构造函数
weak_ptr
需要注意的是,C++11标准虽然将 weak_ptr 定位为智能指针的一种,但该类型指针通常不单独使用(没有实际用处),只能和 shared_ptr 类型指针搭配使用。甚至于,我们可以将 weak_ptr 类型指针视为 shared_ptr 指针的一种辅助工具,借助 weak_ptr 类型指针, 我们可以获取 shared_ptr 指针的一些状态信息,比如有多少指向相同的 shared_ptr 指针、shared_ptr 指针指向的堆内存是否已经被释放等等。
当 weak_ptr 类型指针的指向和某一 shared_ptr 指针相同时,weak_ptr 指针并不会使所指堆内存的引用计数加 1;同样,当 weak_ptr 指针被释放时,之前所指堆内存的引用计数也不会因此而减 1。也就是说,weak_ptr 类型指针并不会影响所指堆内存空间的引用计数。
除此之外,weak_ptr 模板类中没有重载 * 和 -> 运算符,这也就意味着,weak_ptr 类型指针只能访问所指的堆内存,而无法修改它。
weak_ptr的使用
- 基本的创建方法与前两个相似,这里不进行过多讲解,直接讲解平常weak_ptr的使用
- weak_ptr更长指向某一shared_ptr指针所拥有的堆内存,因为在构建weak_ptr指针对象时,可以利用已有的shared_ptr对其进行初始化
std::shared_ptr<int> sp (new int);
std::weak_ptr<int> wp3 (sp);
注: weak_ptr不会导致shared_ptr引用计数的增加或者减少