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
}
- gxx_base(二) 智能指针
- 智能指针二
- scoped_ptr智能指针(二)
- 智能指针(二)
- 智能指针(二):scoped_ptr
- 智能指针(二)
- 浅析智能指针二
- C++智能指针<二>
- C++ STL 智能指针(二)
- 条款二十八: 智能指针
- C++智能指针(二):模拟实现三种智能指针
- 智能指针(二):shared_ptr实现原理
- 一步一步 实现智能指针(二)
- 智能指针总结及应用(二)
- 智能指针(二):shared_ptr实现原理
- C++之智能指针(二)
- 智能指针(二):shared_ptr实现原理
- 88 boost智能指针(二)
- Linux中的进程讲解
- IntelliJ IDEA开发工具详细安装步骤
- 智能指针初探
- 接触linux系统中遇到的各个问题及解决方案
- Git新建本地分支与远程分支关联问题:git branch --set-upstream
- gxx_base(二) 智能指针
- hdu_1285_拓扑排序入门_数组模拟_队列优化
- 《汇编语言》-第一章:基础知识
- promise的学习心得记录
- Failed to load class "org.slf4j.impl.StaticLoggerBinder" 解决方法
- 【hpu oj 1009 QAQ的区间价值 思维】
- http缓存机制
- java.lang.ClassNotFoundException web项目加载时找不到类
- jq杂记