Author:GuangshengZhou
QQ: 825672792
智能指针
C++内存回收机制全靠程序员手动解决, 很多时候稍不留神就会存在内存泄漏,造成严重后果。现代C++引入了智能指针,对内存进行动态管理(RAII),极大的提高了C++编程效率。
现在我们来实现几个常用的智能指针(auto_ptr、share_ptr、weak_ptr),加深对智能指针的理解。
auto_ptr 实现
template<typedef T>
class auto_ptr{
public:
//desc: explicit显示申明,防止隐式转换带来隐患,比如赋值操作。(默认implicit)
//用于构造函数,一个参数或者首参除外其他参数有默认值且只传首参时有效
explicit auto_ptr(T *ptr):m_ptr(ptr), m_bown(m_ptr != nullptr){
}
~auto_ptr(){
delete m_ptr;
}
auto_ptr(const auto_ptr<T> & autoptr):m_bown(autoptr.isown())m_ptr(autoptr.release()){
}
auto_ptr& operator =(const auto_ptr<T> & autoptr){
if(&autoptr == this){
return *this;
}
relsease();
m_ptr = autoptr.release();
return *this;
}
T& operator *(){
return *m_ptr;
}
T* operator ->(){
return m_ptr;
}
T* get() const {
return m_ptr;
}
T* release(){
T* bakptr = m_ptr;
m_ptr = nullptr;
m_bown = false;
return bakptr ;
}
void reset(T* ptr){
if(ptr != m_ptr){
delete m_ptr;
m_ptr = ptr;
}
}
bool isown(){
return m_bown;
}
private:
T * m_ptr;
bool m_bown;
};
备注:因为auto_ptr 赋值拷贝均会引起对象变化,因此不能作为STL容器的元素,否则在操作过后容器中的元素为nullptr,悬空使用时会使程序崩溃
share_ptr 实现
template<typedef T>
class share_ptr{
public:
share_ptr():m_pcount(new int(1)), m_ptr(nullptr){
m_pwkcount = new int(0);
}
explicit share_ptr(T *ptr):m_ptr(ptr){
if(m_ptr != nullptr){
m_count = new int(1);
m_pwkcount = new int(0);
}
}
~share_ptr(){
release();
}
share_ptr(const share_ptr<T> & shareptr):m_pcount(shareptr.m_pcount)m_ptr(shareptr.m_ptr){
if(m_pcount != nullptr){
++(*m_pcount);
}
}
share_ptr& operator =(const share_ptr<T> & shareptr){
if(&shareptr== this){
return *this;
}
//relsease();
m_ptr = shareptr.m_ptr;
m_pcount = ++(*shareptr.m_pcount);
return *this;
}
share_ptr(const weak_ptr<T> & weakptr){
m_ptr = weakptr.m_ptr;
m_pcount = weakptr.m_pcount ;
m_pwkcount = weakptr.m_pwkcount
if(*m_pcount == 0){
m_ptr = nullptr;
}
}
T& operator *(){
return *m_ptr;
}
T* operator ->(){
return m_ptr;
}
T* get() const {
return m_ptr;
}
private:
T* release(){
--(*m_pcount);
if(*m_pcount == 0){
delete m_ptr;
m_ptr = nullptr;
delete m_pcount;
if((*m_pwkcount) == 0)){
delete m_pwkcount;
m_pwkcount = nullptr;
}
}
}
public:
T * m_ptr;
int *m_pcount;
int *m_pwkcount;
};
weak_ptr 实现
template<typedef T>
class weak_ptr{
public:
weak_ptr():m_pcount(nullptr), m_ptr(nullptr){
m_pcount = new int(0);
m_pwkcount= new int(0);
}
~weak_ptr(){
release();
}
explicit weak_ptr(const share_ptr<T> & weakptr):m_pcount(weakptr.m_pcount)m_ptr(weakptr.m_ptr){
if(m_pwkcount != nullptr){
++(*m_pwkcount );
}
}
explicit weak_ptr(const weak_ptr<T> & shareptr):m_pcount(shareptr.m_pcount)m_ptr(shareptr.m_ptr){
if(m_pwkcount != nullptr){
++(*m_pwkcount );
}
}
weak_ptr& operator =(const weak_ptr<T> & weakptr){
if(&weakptr== this){
return *this;
}
//relsease();
m_ptr = weakptr.m_ptr;
m_pcount = weakptr.m_pcount;
++(*m_pwkcount) ;
return *this;
}
weak_ptr& operator =(const share_ptr<T> & shareptr){
//relsease();
m_ptr = shareptr.m_ptr;
m_pcount = shareptr.m_pcount;
++(*m_pwkcount) ;
return *this;
}
share_ptr<T> lock(){
return share_ptr<T>(*this);
}
bool expired(){
if(m_pcount != nullptr && *m_pcount != 0){
return false;
}
return true;
}
T& operator *(){
return *m_ptr;
}
T* operator ->(){
return m_ptr;
}
T* get() const {
return m_ptr;
}
private:
T* release(){
--(*m_pwkcount);
//weak_ptr 绝对不要操作share_ptr 内存
if(*m_pcount == 0 && *m_pwkcount == 0){
delete m_pcount;
if((*m_pwkcount) == 0)){
delete m_pcount;
m_pcount= nullptr;
delete m_pwkcount;
m_pwkcount = nullptr;
}
}
}
public:
T * m_ptr;
int *m_pcount;
int *m_pwkcount;
};
总结
boost中智能指针实现比上面的实现复杂得多,但基本思想是一样的