本文共 3607 字,大约阅读时间需要 12 分钟。
他能保证在你的代码在引发异常时,不会引起内存泄漏或诸多问题
例如当你在申请一段空间后还没来得及释放,中间的代码就引发异常,导致内存泄漏
当你用fopen打开一个文件,还没fclose的时候中间的代码又引发异常。
(1)以指针的行为方式访问所管理的对象,需要重载指针->操作符;
(2)解引用(Dereferencing),获取所管理的对象,需要重载解引用*操作符;
(3)智能指针在其声明周期结束时自动销毁其管理的对象;
(4)引用计数、写时复制、赋值即释放对象拥有权限、控制权限转移。
#pragma once #include#include using namespace std; struct AA { int a1; int a2; }; //模拟智能指针 template class AutoPtr { public: AutoPtr(T* ptr) :_ptr(ptr) {} AutoPtr(AutoPtr & Ap) //浅拷贝 { _ptr = Ap._ptr; Ap._ptr = NULL; //管理权转移,Ap._ptr变成空指针 } AutoPtr & operator=(AutoPtr & 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; };
#include "AutoPtr.h" void TestAutoPtr() { AutoPtrap1 = new AA; (*ap1).a1 = 10; ap1->a1 = 20; AutoPtr ap2(ap1); (*ap2).a2 = 30; ap2->a1 = 40; AutoPtr ap3 = ap2; } int main() { TestAutoPtr(); system("pause"); return 0; }
#pragma once #include#include using namespace std; template class ScopedPtr { public: ScopedPtr(T* ptr) :_ptr(ptr) {} ~ScopedPtr() { delete _ptr; } T* operator->() { return _ptr; } T& operator*() { return *_ptr; } protected: ScopedPtr & operator=(const ScopedPtr & ap); /*只声明不定义*/ ScopedPtr(const ScopedPtr & ap); /*当外界想要让ScopedPtr类指针赋值或重载时就会报错*/ /*并且在protected模式下,外界不能定义*/ protected: T* _ptr; };
#include "ScopedPtr.h" struct AA { int a1; int a2; }; void TestScopedPtr() { ScopedPtrap1 = new AA; (*ap1).a1 = 10; ap1->a2 = 20; } int main() { TestScopedPtr(); system("pause"); return 0; }
#pragma once #include#include using namespace std; template class SharedPtr { public: SharedPtr(T* ptr) :_ptr(ptr) ,_refCount(new int(1)) //此时有一个指针指向这块儿被开辟的空 {} SharedPtr(SharedPtr & Sp) :_ptr(NULL) ,_refCount(new int(0)) { _ptr = Sp._ptr; //浅拷贝 _refCount = Sp._refCount; ++Sp._refCount[0]; //计数器加一 } SharedPtr & operator=(SharedPtr & 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; };
#include "SharedPtr.h" struct AA { int a1; int a2; }; int main() { SharedPtrsp1 = new AA; (*sp1).a1 = 10; sp1->a2 =20; SharedPtr sp2(sp1); SharedPtr sp3 = new AA; (*sp3).a1 = 30; sp3->a2 =40; sp1 = sp3; sp2 = sp3; system("pause"); return 0; }
转载地址:http://evgbb.baihongyu.com/