AutoPtr ScopedPtr SharedPtr
智能指针 1.为什么引进智能指针:2.什么是智能指针 几种智能指针 AutoPtrScopedPtrSharedPtr
他能保证在你的代码在引发异常时,不会引起内存泄漏或诸多问题 例如当你在申请一段空间后还没来得及释放,中间的代码就引发异常,导致内存泄漏 当你用fopen打开一个文件,还没fclose的时候中间的代码又引发异常。
(1)以指针的行为方式访问所管理的对象,需要重载指针->操作符; (2)解引用(Dereferencing),获取所管理的对象,需要重载解引用*操作符; (3)智能指针在其声明周期结束时自动销毁其管理的对象; (4)引用计数、写时复制、赋值即释放对象拥有权限、控制权限转移。
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.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.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;}