一、智能指针(shared_ptr)
1.观察器
get | 返回存储的指针 |
---|---|
operator*/operator-> | 解引用存储的指针 |
operator[] | 提供到被存储数组的带下标访问 |
use_count | 返回shared_ptr所指对象的引用计数 |
unique | 检查所管理对象是否仅由当前shared_ptr的实例管理 |
operator bool | 检查是否有关联的管理对象 |
owner_before | 提供基于拥有者的共享指针排序 |
2.共享指针
共享指针可以同时拥有一块资源。
#ifndef MY_SHARED_PTR_H
#define MY_SHARED_PTR_H
#include<atomic>
template<class _Ty>
class MyDeletor
{
public:
//MyDeletor() = default;
MyDeletor() {}
void operator()(_Ty* ptr) const
{
if (ptr != nullptr)
{
delete ptr;
}
}
};
template<class _Ty>
class MyDeletor<_Ty[]>
{
public:
MyDeletor() = default;
void operator()(_Ty* ptr) const
{
if (ptr != nullptr)
{
delete[]ptr;
}
}
};
template<class _Ty>
class RefCnt
{
public:
_Ty* mptr;
//int ref;
std::atomic_int ref;
public:
RefCnt(_Ty* p = nullptr) :mptr(p), ref(mptr != nullptr) {}
~RefCnt() {}
};
template<class _Ty, class _Dx = MyDeletor<_Ty> >
class my_shared_ptr // thread;
{
public:
my_shared_ptr(_Ty* p = nullptr) :ptr(nullptr)
{
if (p != nullptr)
{
ptr = new RefCnt(p);
}
}
my_shared_ptr(const my_shared_ptr& _Y) :ptr(_Y.ptr)
{
if (ptr != nullptr)
{
ptr->ref += 1;
}
}// my_shared_ptr<Object> op2(op1);
my_shared_ptr(my_shared_ptr&& _Y) :ptr(_Y.ptr)//移动构造函数
{
_Y.ptr = nullptr;
}// my_shared_ptr<Object> op2(std::move(op1));
operator bool() const { return ptr != nullptr; }
my_shared_ptr& operator=(const my_shared_ptr& _Y)//普通对象赋值语句
{
if (this == &_Y || this->ptr == _Y.ptr) return *this;
if (ptr != NULL && --ptr->ref == 0)
{
mDeletor(ptr);
}
ptr = _Y.ptr;
if (ptr != nullptr)
{
ptr->ref += 1;
}
return *this;
}
my_shared_ptr& operator=(my_shared_ptr&& _Y) //移动赋值函数:将资源进行转移,源对象失去资源使用权
{
if (this == &_Y) return *this;
if (this->ptr == _Y.ptr && this->ptr != nullptr && _Y.ptr != nullptr)
{
this->ptr->ref -= 1;
_Y.ptr = nullptr;
return *this;
}
if (this->ptr != nullptr && --ptr->ref == 0)
{
mDeletor(ptr);
}
ptr = _Y.ptr;
_Y.ptr = nullptr;
return *this;
}
void reset(_Ty* p = nullptr)
{
if (this->ptr != nullptr && --this->ptr->ref == 0)
{
mDeletor(ptr);
}
ptr = new RefCnt<_Ty>(p);
}
~my_shared_ptr()
{
if (this->ptr != nullptr && --this->ptr->ref == 0)//引用计数为0的时候,说明没有指针指向才可以释放
{
mDeletor(ptr->mptr);
delete ptr;
}
ptr = nullptr;
}
_Ty* get() const//获得指针
{
return ptr->mptr;
}
_Ty& operator*() const//重载*
{
return *get();
}
_Ty* operator->() const//重载->符号
{
return get();
}
size_t use_count() const//计算有多少对象拥有此资源
{
if (this->ptr == nullptr) return 0;
return this->ptr->ref;
}
void swap(my_shared_ptr& r)//交换对象(交换对象指针)
{
std::swap(this->ptr, r.ptr);
}
private:
RefCnt<_Ty>* ptr;
_Dx mDeletor;
};
template<class _Ty, class _Dx >
class my_shared_ptr<_Ty[], _Dx>
{
public:
my_shared_ptr(_Ty* p = nullptr) :ptr(nullptr)
{
if (p != nullptr)
{
ptr = new RefCnt(p);
}
}
my_shared_ptr(const my_shared_ptr& _Y) :ptr(_Y.ptr)
{
if (ptr != nullptr)
{
ptr->ref += 1;
}
}// my_shared_ptr<Object> op2(op1);
my_shared_ptr(my_shared_ptr&& _Y) :ptr(_Y.ptr)
{
_Y.ptr = nullptr;
}// my_shared_ptr<Object> op2(std::move(op1));
operator bool() const { return ptr != nullptr; }
my_shared_ptr& operator=(const my_shared_ptr& _Y) //
{
if (this == &_Y || this->ptr == _Y.ptr) return *this;
if (ptr != NULL && --ptr->ref == 0)
{
mDeletor(ptr->mptr);
delete ptr;
}
ptr = _Y.ptr;
if (ptr != nullptr)
{
ptr->ref += 1;
}
return *this;
}
my_shared_ptr& operator=(my_shared_ptr&& _Y) // move operator =
{
if (this == &_Y) return *this;
if (this->ptr == _Y.ptr && this->ptr != nullptr && _Y.ptr != nullptr)
{
this->ptr->ref -= 1;
_Y.ptr = nullptr;
return *this;
}
if (this->ptr != nullptr && --ptr->ref == 0)
{
mDeletor(ptr->mptr);
delete ptr;
}
ptr = _Y.ptr;
_Y.ptr = nullptr;
return *this;
}
void reset(_Ty* p = nullptr)
{
if (this->ptr != nullptr && --this->ptr->ref == 0)
{
mDeletor(ptr->mptr);
delete ptr;
}
ptr = new RefCnt<_Ty>(p);
}
~my_shared_ptr()
{
if (this->ptr != nullptr && --this->ptr->ref == 0)
{
mDeletor(ptr->mptr);
delete ptr;
}
ptr = nullptr;
}
_Ty* get() const { return ptr->mptr; }
_Ty& operator*() const
{
return *get();
}
_Ty* operator->() const
{
return get();
}
size_t use_count() const
{
if (this->ptr == nullptr) return 0;
return this->ptr->ref;
}
void swap(my_shared_ptr& r)
{
std::swap(this->ptr, r.ptr);
}
_Ty& operator[](const int idx) const
{
return ptr->mptr[idx];
}
private:
RefCnt<_Ty>* ptr;
_Dx mDeletor;
};
#endif
3.相互引用
导致对象无法释放,所以编译错误
#include<iostream>
using namespace std;
class Child;
class Parent
{
shared_ptr<Child> child;
Parent()
{
cout << "Parent" << endl;
}
~Parent()
{
cout << "~Parent" << endl;
}
void hi()
{
cout << "hello" << endl;
}
};
class Child
{
public:
shared_ptr<Parent> parent;
Child()
{
cout << "Child" << endl;
}
~Child()
{
cout << "~Child" << endl;
}
};
void fun()
{
shared_ptr<Parent> p = make_shared<Parent>();
shared_ptr<Parent> c = make_shared<Child>();
p->child = c;
p->parent = p;
c->parent->hi();
}