智能指针 AutoPtr ScopedPtr SharedPtr

1.为什么引进智能指针:

他能保证在你的代码在引发异常时,不会引起内存泄漏或诸多问题 
例如当你在申请一段空间后还没来得及释放,中间的代码就引发异常,导致内存泄漏 
当你用fopen打开一个文件,还没fclose的时候中间的代码又引发异常。

2.什么是智能指针

(1)以指针的行为方式访问所管理的对象,需要重载指针->操作符; 
(2)解引用(Dereferencing),获取所管理的对象,需要重载解引用*操作符; 
(3)智能指针在其声明周期结束时自动销毁其管理的对象; 
(4)引用计数、写时复制、赋值即释放对象拥有权限、控制权限转移。

几种智能指针

AutoPtr

AutoPtr.h

#pragma once

#include <iostream>
#include <windows.h>

using namespace std;

struct AA
{
int a1;
int a2;
};


//模拟智能指针

template <class T>
class AutoPtr
{
public:
AutoPtr(T* ptr)
:_ptr(ptr)
{}

AutoPtr(AutoPtr<T>& Ap) //浅拷贝
{
_ptr = Ap._ptr;
Ap._ptr = NULL; //管理权转移,Ap._ptr变成空指针
}

AutoPtr<T>& operator=(AutoPtr<T>& ap)
{
if (this != ap) //如果不是自己给自己赋值
{
delete _ptr;
_ptr = ap._ptr;
ap._ptr = NULL;
}
}

T* operator->()
{
return _ptr;
}

T& operator*()
{
return *_ptr;
}

~AutoPtr()
{
delete _ptr;
}
protected:
T* _ptr;
};

test.cpp

#include "AutoPtr.h"

void TestAutoPtr()
{
AutoPtr<AA> ap1 = new AA;
(*ap1).a1 = 10;
ap1->a1 = 20;

AutoPtr<AA> ap2(ap1);
(*ap2).a2 = 30;
ap2->a1 = 40;

AutoPtr<AA> ap3 = ap2;

}

int main()
{
TestAutoPtr();
system("pause");
return 0;

}

ScopedPtr

ScopedPtr.h

#pragma once

#include <iostream>
#include <windows.h>

using namespace std;

template<class T>
class ScopedPtr
{
public:
ScopedPtr(T* ptr)
:_ptr(ptr)
{}

~ScopedPtr()
{
delete _ptr;
}

T* operator->()
{
return _ptr;
}

T& operator*()
{
return *_ptr;
}
protected:
ScopedPtr<T>& operator=(const ScopedPtr<T>& ap); /*只声明不定义*/
ScopedPtr(const ScopedPtr<T>& ap); /*当外界想要让ScopedPtr类指针赋值或重载时就会报错*/
/*并且在protected模式下,外界不能定义*/

protected:
T* _ptr;
};


test.cpp

#include "ScopedPtr.h"

struct AA
{
int a1;
int a2;
};

void TestScopedPtr()
{
ScopedPtr<AA> ap1 = new AA;
(*ap1).a1 = 10;
ap1->a2 = 20;
}

int main()
{
TestScopedPtr();
system("pause");
return 0;
}
SharedPtr

SharedPtr.h

#pragma once

#include <iostream>
#include <windows.h>

using namespace std;

template<class T>
class SharedPtr
{
public:
SharedPtr(T* ptr)
:_ptr(ptr)
,_refCount(new int(1)) //此时有一个指针指向这块儿被开辟的空
{}

SharedPtr(SharedPtr<T>& Sp)
:_ptr(NULL)
,_refCount(new int(0))
{
_ptr = Sp._ptr; //浅拷贝
_refCount = Sp._refCount;
++Sp._refCount[0]; //计数器加一
}

SharedPtr<T>& operator=(SharedPtr<T>& Sp)
{
if (_ptr != Sp._ptr)
{
--_refCount[0];
//判断this是否为最后一个指针
if (0 == _refCount[0]) //当前_ptr是最后一个指针,释放空间
{
delete _ptr;
delete _refCount;
}
_ptr = Sp._ptr; //浅拷贝
_refCount = Sp._refCount;
++Sp._refCount[0]; //计数器加一
}
return *this;
}
T* operator->() //'*'/'->'运算符重载,让SharedPtr类的对象能像普通指针一样使用
{
return _ptr;
}

T& operator*()
{
return *_ptr;
}

~SharedPtr()
{
if (0 == --_refCount[0]) //若_ptr维护的这段空间还有别的指针维护则不释放,else释放空间
{
delete _ptr;
delete _refCount;
_ptr = NULL;
_refCount = NULL;
}
}
protected:
T* _ptr;
int* _refCount;
};

test.cpp

#include "SharedPtr.h"

struct AA
{
int a1;
int a2;
};


int main()
{
SharedPtr<AA> sp1 = new AA;
(*sp1).a1 = 10;
sp1->a2 =20;

SharedPtr<AA> sp2(sp1);

SharedPtr<AA> sp3 = new AA;
(*sp3).a1 = 30;
sp3->a2 =40;
sp1 = sp3;
sp2 = sp3;


system("pause");
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值