gxx_base(二) 智能指针

gxx_base(二) 智能指针


为什么要使用智能指针?
在很多时候,为了提高程序的运行速度,经常需要引用同一内存块,可能多处都用到这一块内存,但不知道什么时候该释放,因此引入智能指针,对内存进行引用计数管理。

当有引用时,引用计数自增,当引用结束时,引用计数自减, 引用计数变为0时,释放指针指向的内存。

在 上一章中介绍了 GxxObject类, 它提供了 retain,release方法来增加引用计数和减小引用计数,直接用这个2个方法,会导致代码很难维护,  容易用错或者忘记调用它们,导致出现野指针或内存泄露问题。使用智能指针来维护引用计数,会让这个工作变得很简单。

众所周知,局部对象生命周期结束时,编译器会自动调用局部对象的析构函数,利用这个特性, 智能指针对象在构造时调用retain,在析构时调用release。

在下面这段代码中查看注释,更能容易理解智能指针的工作原理

template<class _Ty>

class GxxAutoPtr

{

public:

typedef _Ty element_type;


/*explicit*/ GxxAutoPtr(_Ty* _Ptr = 0)

: _Myptr(_Ptr)

{

// 在构造函数中调用 retain

if (_Ptr) _Myptr->retain();

}

GxxAutoPtr(const GxxAutoPtr<_Ty>& _Right)

{

// 在拷贝构造函数中也调用 retain

if (_Myptr == _Right.get()){

if (_Myptr) _Myptr->retain();

}else{

_Myptr = _Right.get();

if (_Myptr) _Myptr->retain();

}

}

template<class _Other>

GxxAutoPtr(GxxAutoPtr<_Other>& _Right)

{

// 在拷贝构造函数中也调用 retain

if (_Myptr == _Right.get()){

if (_Myptr) _Myptr->retain();

}else{

_Myptr = _Right.get();

if (_Myptr) _Myptr->retain();

}

}

~GxxAutoPtr()

{

// 在析构函数中调用release

if (_Myptr) _Myptr->release();

}

_Ty& operator*() const

{ // 重载* 操作符,用起来感觉像直接使用指针的*操作符一样

return (*_Myptr);

}


_Ty *operator->() const

{ // 重载->操作符, 用起来感觉像直接使用指针的->操作符一样

return (&**this);

}


_Ty* get() const

{

return _Myptr;

}


template<class _Other>

operator GxxAutoPtr<_Other>()

{

return (GxxAutoPtr<_Other>(*this));

}

operator _Ty* () const

{

// 将智能指针对象隐式的转为换为指针

return _Myptr;

}


GxxAutoPtr<_Ty>& operator = (_Ty* _Ptr)

{

// 重载=操作符,使得指针可以直接赋值给智能指针对象

// 两个指针相同,引用计数无需变化,什么也不做

if (_Myptr == _Ptr)

return *this;

// 将旧的指针对象的引用计数减少,因为本智能指针对象不再用它了

if (_Myptr) _Myptr->release();

_Myptr = _Ptr;

// 本智能指针引用新的指针对象了, 既然用了,引用计数也当然要跟着增加

if (_Myptr) _Myptr->retain();


return *this;

}


GxxAutoPtr<_Ty>& operator = (GxxAutoPtr<_Ty>& _Right)

{

// 重载=操作符,使得智能指针对象之间也可以赋值

if (_Myptr == _Right.get())

return *this;

if (_Myptr) _Myptr->release();

_Myptr = _Right.get();

if (_Myptr) _Myptr->retain();


return *this;

}


private:

_Ty* _Myptr;

};


下面举例实例化这个智能指针模板类:
class A : public GxxObject

{

GXX_CREATE_FUNC(A);

public:

int a, b;

};

typedef GxxAutoPtr<A> APtr;

void Func(APtr tmpPtr)

{

tmpPtr->a *= 10;

tmpPtr->b *= 10;

}

void main() 

{


APtr p1 = A::create();

p1->a = 10;

p1->b = 12;

printf("%d,%d\n", p1->a, p1->b); // 输出 10,12

APtr p2 = p1;

printf("%d,%d\n", p2->a, p2->b); // 输出 10,12

Func(p2);

printf("%d,%d\n", p1->a, p1->b); // 输出 100,120


}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值