gxx_base(二) 智能指针

来源:互联网 发布:如何关闭mac更新系统 编辑:程序博客网 时间:2024/06/06 00:14

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(constGxxAutoPtr<_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>

operatorGxxAutoPtr<_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


}


原创粉丝点击