C++——模版:智能指针smart_ptr

来源:互联网 发布:斗蟹软件下载 编辑:程序博客网 时间:2024/05/16 01:36

需求分析:

auto_ptr实现了在类对象析构的时候自动delete其管理的指针,但是如果使用不好,两个auto_ptr对象管理同一个指针对象的时候,就会造成重复删除的问题


编译环境:

visual studio 2010


解决方案:

是用统计计数来觉得是否最终释放即可,所以计数是和类型相关的,管理同一种的指针对象用的计数是同一个,所以最后使用静态成员变量来统计。考虑线程安全我们使用InterlockedIncrement和InterlockedDecrement来实现计数的增加和减少

[smart_ptr.h]

template <class T>class smart_ptr{public:    smart_ptr(){        m_pPtr = NULL;    }    smart_ptr( T* p ){        m_pPtr = p;        InterlockedIncrement( &m_nCount );    }    smart_ptr( smart_ptr<T>& p ){    // 拷贝构造函数        *this = p;    }    ~smart_ptr(){    // 析构只减少引用计数        DecCount();    }    T* operator->(){    // 重载->操作符号        return m_pPtr;    }    T& operator*(){    // 重载*操作符号        return *m_pPtr;    }    smart_ptr& operator=(const smart_ptr& rtPtr){    //重载赋值操作符        if( *this != rtPtr ){            m_pPtr = rtPtr.m_pPtr;            InterlockedIncrement( &m_nCount );        }        return *this;    }    smart_ptr& operator=(T* p){    //重载赋值操作符        if( m_pPtr != p ){            m_pPtr = p;            InterlockedIncrement( &m_nCount );        }        return *this;    }    int GetCount(){    // 获得当前引用计数        return m_nCount;    }    T* GetPtr(){        return m_pPtr;    }private:    void DecCount(){    // 减少引用计数        InterlockedDecrement( &m_nCount );        if( m_nCount == 0 ){            delete m_pPtr;        }    }     T* m_pPtr;    static long m_nCount;}; // 模版类,计数静态成员初始化template <class T>long smart_ptr<T>::m_nCount = 0;

[PtrTest.cpp]

#include <crtdbg.h>    // 测试内存是否泄漏#include <Windows.h>   // InterLockedIncrement头文件#include <auto_ptr.h>#include <smart_ptr.h>void Func( smart_ptr<TestClass> temp ){// 接受smart_ptr类型函数    temp->m_nValue = 2;}void Func( auto_ptr<TestClass> temp ){// 接受auto_ptr类型函数    temp->m_nValue = 3;}void TestMain(){// 我们单独写一个测试主函数    auto_ptr<TestClass> tempAutoPtr( new TestClass() );    // 执行下面函数的时候tempAutoPtr管理的指针构造形参的过程中就释放了    // (函数执行完毕,形参释放,为了防止重复删除)    // Func( tempAutoPtr );    // TestClass* pPtr = tempAutoPtr.GetPtr();    smart_ptr<TestClass> tempSmartPtr;    // 赋值操作,增加引用计数(1)    tempSmartPtr = tempAutoPtr.GetPtr();    // 构造形参的时候,增加引用计数(2)    // 函数执行完毕,形参释放,减少引用次数 (1)    Func( tempSmartPtr );    // 测试函数结束    // tempSmartPtr析构减少引用计数(0)    // tempSmartPtr delete其管理的指针}int _tmain(int argc, _TCHAR* argv[]){    TestMain();    // 所以我们可以在此处检测是否内存泄漏    _CrtDumpMemoryLeaks();    return 0;}


返回:

C/C++——模版相关知识

原创粉丝点击