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

来源:互联网 发布:湖人凯尔特人2010数据 编辑:程序博客网 时间:2024/05/16 10:40

需求分析:

C++中,直接使用指针是很方便的,但是带来的问题就是内存泄漏,new出来的内存,必须调用delete去销毁,否则就存在内存泄漏,当内存反复泄漏的时候,就可能造成程序可用的内存不足。


编译环境:

visual studio 2010


解决方案:

如果对象是在栈上创建的时候,对象在出了生命周期的时候,会自己释放。而正是这种特性,我们可以利用起来,达到自动释放指针的目的,这样在使用指针的时候就会更加畅快。
因为任何对象都可以有指针,所以我们这个管理指针的类就需要使用模版功能来适应各种各样的指针。

[auto_ptr.h]

#ifndef NULL#define NULL 0#endiftemplate <class T>class auto_ptr() {public:    explicit auto_ptr( T* p ) : m_pPtr( p ) {    // 构造函数    }    auto_ptr( auto_ptr<T>& rtPtr ) : m_pPrt( rtPtr.Detach() ){    // 拷贝构造函数    // 原来的函数需要调用Detach,否则在形参传递的时候,就会调用拷贝构造函数,因为作为参数,所以形参管理的指针必须和传入参数一致,才能得到一样的效果,但是同样就涉及到,析构的时候,同样的内存地址遭到两次释放,就会出错。    }    ~auto_ptr() {    // 析构时候自动释放指针        delete m_pPtr;     }    T* Detach(){    // 分离管理的指针对象        T* pPrev = m_pPtr;        m_pPtr = NULL;        return pPrev;           }    void Attach( T* pNew ){    // 附加新的指针对象        if( m_pPtr != pNew ){            delete m_pPtr;            m_pPtr = pNew;        }    }    T* operator->(){    // 重载->操作符号        return m_pPtr;    }    T& operator*(){    // 重载*操作符号        return *m_pPtr;    }    auto_ptr<T>& operator=( auto_ptr<T>& rtPtr){    // 重载等号操作符号            if ( this != &rtPtr ){            Attach( rhs.Detach() );        }            return *this;        }    private:    T* m_pPtr;};

检测内存泄漏:
[auto_ptr.h]

template <class T>class auto_ptr() {    //...    ~auto_ptr(){    // 析构函数,检查内存泄漏需要添加在此处        delete m_pPtr;        _CrtDumpMemoryLeaks();    }}

[PtrTest.cpp]

#include <crtdbg.h>   // 内存泄漏需要添加该头文件#include "auto_ptr.h"class TestClass{public:    TestClass() : m_nValue(1) {}    int m_nValue;};int _tmain(int argc, _TCHAR* argv[]){    auto_ptr<TestClass> tempPtr( new TestClass() );    // 因为变量析构是超出函数生命周期以后,如果添加到此处检测则永远提示泄漏,因为析构函数尚未执行    // _CrtDumpMemoryLeaks();    // 调用该函数,如果返回的指针未作处理,也是内存泄漏    tempPtr.Detach();    return 0;       }

运行结果:

这里写图片描述

这里写图片描述


返回:

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