您的位置:首页 > 其它

别人写的一个智能指针的实现,不知道能不能行

2005-09-13 17:05 501 查看
一个智能指针的实现[/b]
发布时间: 2004-06-30 21:36:14 来源/作者:CSDN
用C++写程序的人都知道内存泄漏这个问题(除非他从来不动态分内存),对STL有了解的人都知道有auto_ptr这么个智能指针,可因为它只能有一个拥有权,所以不能支持标准容器,一直不太喜欢这点。能开发出一个共享访问的智能指针就好多了(这有点像Windows内核对象)。所以,需要有个对象来管理计数问题,这个对象只能和要管理的指针共存亡,当有新的对象指向这块内存时只要把指针给它,计数加1,当一个对象析构时,只要把计数减1,是否释放是这个管理类的事儿。当计数为0时就可以自己了断了。下面我就阐述下我是怎么设计这个类的。

Template class shared_data

shared_data是管理指针并计数的类,我们看看它都需要写哪些函数 template<class T> class shared_data { private: friend class shared_ptr<T>; explicit shared_data(T* pT):_M_ptr(pT); ~shared_data() ; void operator++ (); operator-- (); T& operator* () const ; T* operator-> () const; bool operator== (T* pT) const ; T* get() ; int use_count() ; private: T* _M_ptr; unsigned int _M_nCount; }; shared_ptr是我们真正要用的,所以,shared_data里的一切我们做成private就可以了,只要让shared_ptr成为自己的友员。
l 操作很简单,我们先看数据区:
1. T* _M_ptr;
这是我们分配出来的对象T的指针,也是我们管理的对象。
2. unsigned int _M_nCount;
这是我们的计数变量,初始时是1,当为0时就把自己给delete。

l 我们再看操作

1. 构造函数用来把管理的指针存入_M_ptr,析构用来释放_M_ptr。
2. operator++()和operator—()用来增加和减少计数,在operator—()中做计数是否为0,决定在什么时候释放资源。
3. operator==()用来判断操作符右边的T指针是否与管理的T指针是同一地址。
4. operator*和operator->就不用说了吧。
5. get()用来返回T*。
6. use_count()用来获取当前有多少个引用。

Template class shared_ptr

shared_ptr是用来定义和操作shared_data的类,所有同类型的shared_ptr可以有多可实例,但只有一个所共享的管理类shared_data,当两个shared_ptr类或shared_ptr和对像T的指针T*操作时,只需要对shared_data进行++和—即可。template<class T> class shared_ptr { typedef shared_data<T> element; public: explicit shared_ptr(T* pT):_M_pD(NULL); explicit shared_ptr():_M_pD(NULL){}; ~shared_ptr() ;
// copy constructor shared_ptr(const shared_ptr<T>& rT) ; // assignment operator shared_ptr<T>& operator = (shared_ptr<T>& rT) ; shared_ptr<T>& operator = (T* pT); T& operator* () const ; T* operator-> () const; bool operator== (shared_ptr<T>& rT) const; bool operator== (T* pT) const; void reset(); private: element* get_element()const ; element* _M_pD; };l 我们先看数据区只有一个成员_M_pD,是shared_data对象的指针,有一shared_ptr只能拥有一个shared_data对象,shared_ptr只负责shared_data的分配,不负责释放,其它操作就是对shared_data计数的++和—操作。
l 公用成员函数1. 有两个构造,一个有参数T*,用来直接分配管理类的。一个没有参数,这时的_M_pD为NULL。析构只做shared_data的—操作。2. 拷贝构造函数用来从另一个shared_ptr中获取_M_pD并做计数++操作3. 两个赋值函数一个是对应shared_ptr对象的,而另一个则是对应T*的,不用细说了吧。4. operator*() 和operator->()只是用来调用shared_data的同名函数,因为shared_data所有操作对用户是不可见的。5. operator==() 比shared_data多了一个,这个是用来比较_M_pD的地址是否相同,那个只是调用shared_data的同名函数(同上)。6. reset() 用来置空当前_M_pD,当然也要对它做—操作了。7. 再说最后一个get_element(),一个内部函数,用来返回_M_pD,在赋值时用到。

User Operator

为了说明我们怎么操作这个类,我们先定义一个测试类class CTest{public: CTest(int nId){ cout<<"CTest()"<<endl; m_nId = nId; }
~CTest(){ cout<<"~CTest()"<<endl; }
void ShowId() { cout<<m_nId<<endl; }private: int m_nId;};
下面看下我的测试怎么写的
void main(){ // Test constructor shared_ptr<CTest> t1(new CTest(1)); // Test copy constructor shared_ptr<CTest> t2(t1); // Test assignment operator shared_ptr<CTest> t3; t3 = t2; // Test operator-> t3->ShowId(); // Test operator* (*t3).ShowId(); // Test operator== shared_ptr<CTest> t4(new CTest(1)); shared_ptr<CTest> t5(new CTest(2)); t4 = t5; if (t4 == t5) cout<<"t4 == t5"<<endl; else cout<<"t4 != t5"<<endl; // Test operator== CTest *p = new CTest(123); shared_ptr<CTest> t6(p); if (t6 == p) cout<<"t6 == p"<<endl; else cout<<"t6 != p"<<endl; // Test operator== shared_ptr<CTest> p7; if (p7 == NULL) cout<<"p7 == NULL"<<endl; // Test reset shared_ptr<CTest> t8(new CTest(2)); t8.reset(new CTest(123)); t8->ShowId();
// Test release shared_ptr<CTest> t9(new CTest(9)); t9.release(); cout<<t9.get()<<endl; // Test array shared_ptr<CTest> t10(new CTest(123)); shared_ptr<CTest> t11[100]; for (int i=0;i<100;i++) { t11[i] = t10; }}
由于水平有限,可能有的地方存在问题,欢迎大家加于改善,在此给出全部代码,供大家参考
------别人写的一个智能指针的实现,不知道能不能行
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: