
💗 💗 博客:小怡同学
💗 💗 个人简介:编程小萌新
💗 💗 如果博客对大家有用的话,请点赞关注再收藏 🌞
智能指针的使用及原理
AII(Resource Acquisition Is Initialization)是一种利用对象生命周期来控制程序资源(如内
存、文件句柄、网络连接、互斥量等等)的简单技术。
在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。
std::auto_ptr
c++98版本的库中就提供了auto_ptr的智能指针。下面演示的auto_ptr的使用及问题。
auto_ptr的实现原理:管理权转移的思想,下面简化模拟实现了一份bit::auto_ptr、
cpp
template<class T>
class auto_ptr
{
public:
auto_ptr(T* ptr)
:_ptr(ptr)
{}
auto_ptr(const auto_ptr<T>& ap)
{
_ptr = ap._ptr;
ap._ptr = nullptr;
}
auto_ptr<T>& operator=(const auto_ptr<T>& ap)
{
if (&ap == this)
return *this;
_ptr = ap._ptr;
ap._ptr = nullptr;
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
~auto_ptr()
{
delete _ptr;
}
private:
T* _ptr;
};
std::unique_ptr
unique_ptr的实现原理:简单粗暴的防拷贝,下面简化模拟实现了一份UniquePtr来
cpp
template<class T>
class unique_ptr
{
public:
unique_ptr(T* ptr)
:_ptr(ptr)
{}
unique_ptr(const unique_ptr<T>& ap) = delete;
//防止拷贝
unique_ptr<T>& operator=(const unique_ptr<T>& ap) = delete;
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
~unique_ptr()
{
delete _ptr;
}
private:
T* _ptr;
};
std::shared_ptr
c++11中开始提供更靠谱的并且支持拷贝的shared_ptr
cpp
template<class T>
class shared_ptr
{
public:
//这个函数是模拟仿函数传进来的场景主要作用显示释放内存,其他成员函数调用不了D类型所以在成员变量中加入包装类函数这样类中都能使用这个函数了
template<class D>
shared_ptr(T* ptr, D del)
:_ptr(ptr)
, count(new int(1))
, _del(del)
{
}
shared_ptr(T* ptr)
:_ptr(ptr)
, count(new int(1))
{}
shared_ptr(const shared_ptr<T>& sp)
{
_ptr = sp._ptr;
count = sp.count;
++(*count);
}
shared_ptr<T>& operator=(const shared_ptr<T>& sp)
{
if (this == &sp)
return this;
_ptr = sp._ptr;
count = sp.count;
++(*count++);
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
~shared_ptr()
{
if (--(*count) == 0)
{
_del(_ptr);
delete count;
}
}
private:
T* _ptr;
int* count;
function<void(T*)> _del = [](T* ptr) {delete ptr; };
};
}
shared_ptr会出现循环引用的现象他的解决方案:在引用计数的场景下,节点中的_prev和_next改成weak_ptr就可以了
cpp
template<class T>
class weak_ptr
{
weak_ptr()
:_ptr(nullptr)
{}
weak_ptr(const shared_ptr<T>& sp)
:_ptr(sp._ptr)
{}
weak_ptr<T>& operator=(const shared_ptr<T>& sp)
:_ptr(sp._ptr)
{
return* this;
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
private:
T* _ptr;
};