分享
 
 
 

一个智能指针的实现

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

一个智能指针的实现

用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;

}

}

由于水平有限,可能有的地方存在问题,欢迎大家加于改善,在此给出全部代码,供大家参考

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有