引用计数的对象没有被释放。:引用计数类对象是所有共享智能指针所共有的,因此在堆区通过指针共享。释放时一般通过weak_ptr释放。(注:make_shared缺点之一,shared_ptr销毁时,weak_ptr还存活,则引用计数类对象与资源对象所在的同一片空间会延迟释放(只有最后一个 weak_ptr 离开作用域时, 内存才会被释放. 原本强引用减为 0 时就可以释放的内存, 现在变为了强引用, 弱引用都减为 0 时才能释放,))、
std::shared_ptr 是通过指针保持对象共享所有权的智能指针。多个 shared_ptr 对象可占有同一对象。具体参考 《std::shared_ptr》
#include <iostream>
#include <atomic>
// 仿写shared_ptr
namespace TR {
// 引用计数类
template<typename T>
class RefCnt {
private:
T* mPtr; // 指向对象的指针
std::atomic<int> mCnt; // 原子操作 ++i {指向对象的指针和引用计数}
public:
// 构造函数,空指针引用计数为0,否则为1
RefCnt(T* ptr = nullptr) noexcept :mPtr(ptr), mCnt(0)
{
if (ptr != nullptr) mCnt = 1;
}
// atomic内部函数,获得当前mCnt瞬间值
int load() const noexcept { return mCnt.load(); }
// 重置引用计数
void reset(int ref = 1)noexcept { mCnt = ref; }
// 引用计数增加
void addRef()noexcept { ++mCnt;/* mCnt++ */ }
// 引用计数减少
int delRef()noexcept { return --mCnt; }
// 析构函数
~RefCnt()noexcept {}
};
// 删除器类 -针对单个对象 // 一元仿函数
template<typename T>
struct MyDeletor {
void operator()(T* ptr) const noexcept
{
delete ptr;
}
};
// 删除器类 -针对多个对象 // 一元仿函数
template<typename T>
struct MyDeletor<T[]> {
void operator()(T* ptr) const noexcept
{
delete[] ptr;
}
};
// 智能指针类 // 默认的删除方法
template<typename T, typename Deletor = MyDeletor<T>>
class shared_ptr {
private: // 成员变量
T* mPtr;
RefCnt<T>* mpRefCnt;
private:
// 返回一个删除器对象
Deletor Get_deletor() { return Deletor(); }
private:
// 释放资源函数
void release()
{
if (get() != nullptr) { // 空指针,忽略
if (0 == mpRefCnt->delRef()) // 引用计数器为0时,释放资源
{
Get_deletor()(mPtr); // 使用删除器进行释放
delete mpRefCnt;
}
mPtr = nullptr;
mpRefCnt = nullptr;
}
}
public:
// 构造
shared_ptr(T* ptr = nullptr) noexcept :mPtr(ptr)
{
if(ptr != nullptr) // 空指针不生成引用计数实例
mpRefCnt = new RefCnt<T>(ptr); // 引用计数类生成实例
}
// 拷贝构造
shared_ptr(const shared_ptr& _Y)noexcept
:mPtr(_Y.mPtr), mpRefCnt(_Y.mpRefCnt)
{ // 如果是空指针,不生成引用计数实例
if (mPtr != nullptr) mpRefCnt->addRef();
}
~shared_ptr()noexcept
{
this->release();
}
// 移动构造
shared_ptr(shared_ptr&& _Y) noexcept
{
mPtr = _Y.mPtr;
mpRefCnt = _Y.mpRefCnt;
_Y.mPtr = nullptr;
_Y.mpRefCnt = nullptr;
}
// 赋值函数
shared_ptr& operator=(const shared_ptr& _Y)noexcept
{
//if (this != &_Y) // 防止自赋值
//{
// release(); // 删除原有资源(删除、或引用计数减一)
// if (mPtr != nullptr) // 资源非空,进行赋值
// {
// mPtr = _Y.mPtr; // 赋值资源
// mpRefCnt = _Y.mpRefCnt;// 赋值引用计数
// mpRefCnt->addRef(); // 引用计数++
// }
//}
//return *this;
// 库提供实现方法:调用拷贝,生成临时对象,交换两对象的值
shared_ptr(_Y).swap(*this);
return *this;
}
// 移动赋值函数
shared_ptr& operator=(shared_ptr&& _Y) noexcept
{
//mPtr = _Y.mPtr;
//mpRefCnt = _Y.mpRefCnt;
//_Y.mPtr = nullptr;
//_Y.mpRefCnt = nullptr;
//return *this;
// 库提供实现方法:调用移动构造,生成临时对象,交换两对象的值
shared_ptr(std::move(_Y)).swap(*this);
return *this;
}
// 重置函数
void reset(T* p)noexcept
{ // 库提供实现方法:调用构造函数生成临时对象,交换两对象的值
shared_ptr(p).swap(*this);
}
// 交换函数
void swap(shared_ptr& _Right)noexcept
{
std::swap(mPtr, _Right.mPtr); // 交换资源
std::swap(mpRefCnt, _Right.mpRefCnt); // 交换引用计数实例
}
// 是否独占
bool unique()const noexcept
{
return static_cast<long>(this->use_count()) == 1;
}
public:
// 重载运算符
T* get() const noexcept { return mPtr; }
T& operator*() const noexcept { return *get(); }
T* operator->() const noexcept { return get(); }
explicit operator bool() const noexcept { return get() != nullptr; }
long use_count() const noexcept { return mpRefCnt == nullptr ? 0 : mpRefCnt->load(); }
};
/* ----------------------------- 多对象(数组)版本 ---------------------------- */
// 智能指针类 // 默认的删除方法
template<typename T, typename Deletor >
class shared_ptr<T[], Deletor> {
private: // 成员变量
T* mPtr;
RefCnt<T>* mpRefCnt;
private:
// 返回一个删除器对象
Deletor Get_deletor() { return Deletor(); }
private:
// 释放资源函数
void release()
{
if (get() != nullptr) { // 空指针,忽略
if (0 == mpRefCnt->delRef()) // 引用计数器为0时,释放资源
{
Get_deletor()(mPtr); // 使用删除器进行释放
delete mpRefCnt;
}
mPtr = nullptr;
mpRefCnt = nullptr;
}
}
public:
// 构造
shared_ptr(T* ptr = nullptr) noexcept :mPtr(ptr)
{
if (ptr != nullptr) // 空指针不生成引用计数实例
mpRefCnt = new RefCnt<T>(ptr); // 引用计数类生成实例
}
// 拷贝构造
shared_ptr(const shared_ptr& _Y)noexcept
:mPtr(_Y.mPtr), mpRefCnt(_Y.mpRefCnt)
{ // 如果是空指针,不生成引用计数实例
if (mPtr != nullptr) mpRefCnt->addRef();
}
~shared_ptr()noexcept
{
this->release();
}
// 移动构造
shared_ptr(shared_ptr&& _Y) noexcept
{
mPtr = _Y.mPtr;
mpRefCnt = _Y.mpRefCnt;
_Y.mPtr = nullptr;
_Y.mpRefCnt = nullptr;
}
// 赋值函数
shared_ptr& operator=(const shared_ptr& _Y)noexcept
{
shared_ptr(_Y).swap(*this);
return *this;
}
// 移动赋值函数
shared_ptr& operator=(shared_ptr&& _Y) noexcept
{
shared_ptr(std::move(_Y)).swap(*this);
return *this;
}
// 重置函数
void reset(T* p)noexcept
{
shared_ptr(p).swap(*this);
}
// 交换函数
void swap(shared_ptr& _Right)noexcept
{
std::swap(mPtr, _Right.mPtr); // 交换资源
std::swap(mpRefCnt, _Right.mpRefCnt); // 交换引用计数实例
}
// 是否独占
bool unique()const noexcept
{
return static_cast<long>(this->use_count()) == 1;
}
public:
// 重载运算符
T* get() const noexcept { return mPtr; }
T& operator*() const noexcept { return *get(); }
//T* operator->() const noexcept { return get(); }
T& operator[](int Idx)const noexcept { return get()[Idx]; }
explicit operator bool() const noexcept { return get() != nullptr; }
long use_count() const noexcept { return mpRefCnt == nullptr ? 0 : mpRefCnt->load(); }
};
}
测试类:
// 测试类
class Object {
private:
int mval;
public:
Object(int i = 0)
:mval(i) { std::cout << "construction() val: " << mval << std::endl; }
~Object() { std::cout << "~destruct() val: " << mval << std::endl; }
const int& getVal() { return mval; }
};
测试用例:
int main()
{
// 测试:空指针相互赋值
TR::shared_ptr<Object> a;
TR::shared_ptr<Object> b;
a = b;
std::cout << a.use_count() << " " << b.use_count() << std::endl;
// 相关函数:赋值函数,
// 构造函数:如果传入空指针则不生成RefCnt对象
// use_count:如果是空指针,返回0
// 正常赋值
TR::shared_ptr<Object> a1(new Object(1));
TR::shared_ptr<Object> b1;
b1 = a1;
std::cout << a1.use_count() << " " << b1.use_count() << std::endl;
// 拷贝赋值 & 移动赋值
TR::shared_ptr<Object> osp1(new Object(2));
TR::shared_ptr<Object> osp2(std::move(osp1));
TR::shared_ptr<Object> osp3;
osp3 = std::move(osp2);
std::cout << osp3->getVal() << std::endl;
std::cout << osp1.use_count() << " " << osp2.use_count()
<< " " << osp3.use_count() << std::endl;
// 是否独占
TR::shared_ptr<Object> c(new Object(3));
std::cout << "c 是否独占: " <<std::boolalpha << c.unique() << std::endl;
// 交换
TR::shared_ptr<Object> d(new Object(4));
TR::shared_ptr<Object> e(new Object(5));
d.swap(e);
std::cout << "d: "<< d->getVal() << " " << " e: " << e->getVal() << std::endl;
// 重置
TR::shared_ptr<Object> f(new Object(6));
std::cout << "f: " << f->getVal() << std::endl;
f.reset(new Object(8));
std::cout << "f: " << f->getVal() << std::endl;
// 多对象(数组)创建
// 1.直接使用Object[] 模板参数
TR::shared_ptr<Object[]> sptr1(new Object[3]{11,12,13});
// 2.使用Object[] 模板参数 + TR中的数组回收方式
TR::shared_ptr<Object[], TR::MyDeletor<Object[]>> sptr2(new Object[3]{ 21,22,23 });
// 3.使用Object[] 模板参数 + 指定资源回收方式
struct Object_deletor {
void operator()(Object* p) { delete[]p; }
};
// 打印,operator[] 的重载
for (int i = 0; i < 3; i++) std::cout << sptr1[i].getVal() << " ";
for (int i = 0; i < 3; i++) std::cout << sptr2[i].getVal() << " ";
std::cout << std::endl;
return 0;
}