为什么要用这个auto_ptr,一般的C语言指针不够用吗?如果C++里没有new,那一般的指针就够用了,现在的代码都像这样: int *p=new int[100]; //使用p delete[] p; 使用p的时候,如果突然出了问题,比如丢出异常,就会中止程序,而不能运行delete,造成内存泄漏,所以在使用的时候,经常要做很多判断,比如 if(p){ ... delete[] p;} if(XXX){ delete[] p; throw(xx);} 所以,拿到内存容易,但责任就大啊,所以整个代码被整个乱七八糟,而且程序员还要保持清醒的头脑,一不小心就。。。 STL的auto_ptr就是为了解决这个问题,做的一个封装,在指针的运算过程中,比如*,->,发生错误,丢异常,并在析构的时候delete。 把VC6里的auto_ptr复制下: template<class _Ty> class auto_ptr {public: typedef _Ty element_type; explicit auto_ptr(_Ty *_P = 0) _THROW0() : _Owns(_P != 0), _Ptr(_P) {} auto_ptr(const auto_ptr<_Ty>& _Y) _THROW0() : _Owns(_Y._Owns), _Ptr(_Y.release()) {} auto_ptr<_Ty>& operator=(const auto_ptr<_Ty>& _Y) _THROW0() {if (this != &_Y) {if (_Ptr != _Y.get()) {if (_Owns) delete _Ptr; _Owns = _Y._Owns; } else if (_Y._Owns) _Owns = true; _Ptr = _Y.release(); } return (*this); } ~auto_ptr() {if (_Owns) delete _Ptr; } _Ty& operator*() const _THROW0() {return (*get()); } _Ty *operator->() const _THROW0() {return (get()); } _Ty *get() const _THROW0() {return (_Ptr); } _Ty *release() const _THROW0() {((auto_ptr<_Ty> *)this)->_Owns = false; return (_Ptr); }private: bool _Owns; _Ty *_Ptr; }; 代码在<memory>里,写得比较丑陋,忍住胃看吧。但是它还是有问题,在《C++Primer》里写了一些注意,所以程序员还是要甚用。(听说BOOST里有完全安全的auto_ptr,不知道怎么写的) 我的程序完全是照着那些缺陷做的,是用一个map表保存堆内在的分配情况,比如一个堆上的对象指针被分发给几个auto_ptr,那只有在最后一个析构的时候去delete,怎么实现?用使用计数器,就像文件一样,把堆上的内存看成资源,资源可以被多个‘人’打开,打开一次,计数器+1,关闭一次-1,最后一个关闭的时候进行析构,另外对于数组的情况,只用做一个标记就行了。 (异常部分没写,只做个框架) #include <map>#ifndef HEAPPTR_2007#define HEAPPTR_2007 template<class T>class heap_ptr{ //enum{tag=t}; T* ptr; bool bArray; static std::map<T*,int> use_count;public: heap_ptr():ptr(0){}; heap_ptr(T* q, bool b=false){ bArray=b; attach(q); }; ~heap_ptr(){ detach(); }; // *,->和[]运算符 T& operator*(){ return *ptr; }; T* operator->(){ return ptr; }; T& operator[](int index){ return ptr[index]; }; // 拷贝构造函数和赋值函数 heap_ptr(heap_ptr &hp){ attach(hp.ptr); bArray=hp.bArray; }; heap_ptr& operator=(heap_ptr &hp){ detach(); attach(hp.ptr); bArray=hp.bArray; }; // void attach(T* q){ std::map<T*,int>::iterator it=use_count.find(q); if(it==use_count.end()) { use_count[q]=1; } else { use_count[q]++; } ptr=q; }; void detach(){ if(ptr) { int c=--use_count[ptr]; if(c==0) { use_count.erase(ptr); if(bArray) delete[] ptr; else delete ptr; } } }; }; #define USE_HEAPPTR_ON(TYPE) \ std::map<TYPE*,int> heap_ptr<TYPE>::use_count; #endif 由于只用于堆上的动态内存,所以干脆叫heap_ptr,最后的宏是为了初始化静态成员,如果要使用某个类在堆上的内存,在使用的地方,在全局定义的位置,加上这句宏就可以了。 使用: #include "stdafx.h"#include "heapptr.h"#include <iostream>using namespace std; USE_HEAPPTR_ON(int) void foo1(heap_ptr<int> p){ *p=1;}void foo2(heap_ptr<int> p){ *p=2;}void foo3(heap_ptr<int> p){ p[0]=3;}void foo4(heap_ptr<int> p){ p[1]=4;}int main(int argc, char* argv[]){ printf("Hello World!\n"); heap_ptr<int> p(new int(0)); heap_ptr<int> q(new int[10],true); foo1(p); cout<<*p<<endl; foo2(p); cout<<*p<<endl; foo3(q); foo4(q); cout <<q[0]<<endl <<q[1]<<endl; return 0;}

评论