智能指针shared_ptr的原理、用法和注意事项
1 前言
在实际的C++开发过程中,我们经常会遇到诸如程序运行中突然崩溃、程序运行所用的内存越来越多最终不得不重启等问题,这些问题往往都是内存管理资源不当造成的。比如:
①有些内存资源已经释放,但指向它的指针并没有改变指向,最终成为了野指针,并且后续还在使用;
②有些内存资源已经被释放,后期又试图再释放一次,最终导致重复释放同一块内存会使程序运行崩溃;
③没有及时释放不再使用的内存资源,造成内存泄漏,程序占用的内存资源越来越多。
针对以上情况,C++提供了更友好的内存管理机制,让程序员更专注于开发项目的各个功能上,而不是自己进行内存管理。事实上,显示内存管理的替代方案很早就有了,早在1959年前后,就有人提出“垃圾自动回收”机制,“垃圾”指的是那些不再使用或者没有任何指针指向的内存空间,而“回收”指的是将这些“垃圾”收集起来以便再次利用。
在C++98/03标准中,支持使用anto_ptr智能指针来实现堆内存的自动回收,C++11新标准在废弃auto_ptr的同时,增加了nique_ptr、shared_ptr 以及 weak_ptr 这 3 个智能指针来实现堆内存的自动回收。
智能指针和普通指针用法相似,智能指针的本质是一个模板类,对普通指针进行了封装,通过在构造函数中初始化分配内存,在析构函数中释放内存,达到自己管理内存,不需要手动管理内存的效果,因此智能指针可以在适当时机自动释放分配的内存,即使用智能指针可以很好地避免“忘记释放内存而导致内存泄漏”问题,由此可见,C++开始支持了垃圾回收机制,但是目前支持的程度有限。
接下来对shared_ptr的原理和用法做详细的解释说明。
2 shared_ptr原理
shared_ptr是以类模板的方式实现的,shared_ptr<T>(其中 T 表示指针指向的具体数据类型)的定义位于<memory>头文件,并位于 std 命名空间中,因此在使用该类型指针时,程序中应包含如下 2 行代码:
#include <memory>
using namespace std; //这一行代码不是必须的,如果不添加则在后续使用shared_ptr 智能指针时,就需要明确指明std::
shared_ptr的简单实现如下:
#include<iostream>
#include<mutex>
#include<thread>
using namespace std;
template<class T> //模板类
class Shared_Ptr{
public:
//以普通指针进行构造
Shared_Ptr(T* ptr = nullptr)
:_pPtr(ptr)
, _pRefCount(new int(1))
, _pMutex(new mutex)
{
}
//析构函数
~Shared_Ptr()
{
Release();
}
//拷贝构造函数
Shared_Ptr(const Shared_Ptr<T>& sp)
:_pPtr(sp._pPtr)
, _pRefCount(sp._pRefCount)
, _pMutex(sp._pMutex)
{
AddRefCount();
}
//重载赋值号,使得同一类型的shared_ptr智能指针可以相互赋值
Shared_Ptr<T>& operator=(const Shared_Ptr<T>& sp)
{
if (_pPtr != sp._pPtr)
{
// 释放管理的旧资源
Release();
// 共享管理新对象的资源,并增加引用计数
_pPtr = sp._pPtr;
_pRefCount = sp._pRefCount;
_pMutex = sp._pMutex;
AddRefCount();
}
return *this;
}
// 重载 * 号,获取当前 shared_ptr 智能指针对象指向的数据
T& operator*(){
return *_pPtr;
}
//重载 -> 号,当智能指针指向的数据类型为自定义的结构体时,通过 -> 运算符可以获取其内部的指定成员
T* operator->(){
return _pPtr;
}
//返回同当前 shared_ptr 对象(包括它)指向相同的所有 shared_ptr 对象的数量
int UseCount() {
return *_pRefCount; }
//返回 shared_ptr 对象内部包含的普通指针
T

本文深入探讨了C++11引入的智能指针shared_ptr的工作原理,包括其引用计数和线程安全特性。通过示例展示了shared_ptr的初始化、获取原始指针、与动态数组的交互,以及C++17和C++20新特性。此外,还强调了使用shared_ptr时应注意的潜在问题,如避免循环引用和在多线程环境下确保正确性。
1万+

被折叠的 条评论
为什么被折叠?



