【more effective c++读书笔记】【第5章】技术(4)——Smart Pointers(智能指针)
一、类似C++标准程序库提供的auto_ptr template的智能指针
//Smart.h #ifndef SMART_H #define SMART_H template<typename T> class SmartPtr{ public: SmartPtr(T* realPtr = 0); //构造函数 ~SmartPtr();//析构函数 SmartPtr(SmartPtr& rhs); //拷贝构造函数 SmartPtr& operator=(SmartPtr& rhs);//拷贝赋值运算符 T* get() const; //获取原始指针 T* operator->() const;//重载->运算符 T& operator*() const;//重载*运算符 bool operator!() const;//重载!运算符 template<typename newType> operator SmartPtr<newType>();//隐式转换 private: T* pointer; }; //构造函数 template<typename T> SmartPtr<T>::SmartPtr(T* realPtr = 0) :pointer(realPtr){} //析构函数 template<typename T> SmartPtr<T>::~SmartPtr(){ delete pointer; } //拷贝构造函数 template<typename T> SmartPtr<T>::SmartPtr(SmartPtr<T>& rhs){ pointer = rhs.pointer;//将*pointer的拥有权转移至*this,rhs不再拥有任何东西 rhs.pointer = 0; } //拷贝赋值运算符 template<typename T> SmartPtr<T>& SmartPtr<T>::operator=(SmartPtr<T>& rhs){ if (this == &rhs)////自赋值情况 return *this; delete pointer;//删除目前拥有物 pointer = rhs.pointer;//将*pointer的拥有权转移至*this,rhs不再拥有任何东西 rhs.pointer = 0; return *this; } //获取原始指针 template<typename T> T* SmartPtr<T>::get() const{ return pointer; } //重载->运算符 template<typename T> T* SmartPtr<T>::operator->() const{ return pointer; } //重载*运算符 template<typename T> T& SmartPtr<T>::operator*() const{ return *pointer; } //重载!运算符 template<typename T> bool SmartPtr<T>::operator!() const{ if (pointer == nullptr) return true; return false; } //隐式转换 template<typename T> template<typename newType> SmartPtr<T>::operator SmartPtr<newType>(){ return SmartPtr<newType>(pointer); } #endif //Tmb.h #ifndef TMB_H #define TMB_H #include<iostream> class Top{ public: Top(int i = 0){ iTop = i; } void printT(){ std::cout << iTop << std::endl; } private: int iTop; }; class Middle :public Top{ public: Middle(int i = 0) :Top(i){} void printM(){ printT(); } }; class Bottom :public Middle{ public: Bottom(int i = 0) :Middle(i){} void printB(){ printM(); } private: int iTop; }; #endif //main.cpp #include"Smart.h" #include"Tmb.h" #include<iostream> using namespace std; int main(){ Top* p1 = new Top(1); SmartPtr<Top> sp1(p1); SmartPtr<Top> sp2(sp1);//sp1不指向任何对象 sp2->printT(); SmartPtr<Top> sp3; sp3 = sp2; //拷贝赋值,sp2不指向任何对象 (*sp3).printT(); //sp2->printT();//出错 system("pause"); return 0; }二、运用引用计数的智能指针
//Smart.h #ifndef SMART_H #define SMART_H template<typename T> class SmartPtr;//需要前置声明 ,编译器将友元声明当作类的声明 //辅助类 template<typename T> class RefPtr{ private://成员访问权限全为private,不想让用户直接使用该类 friend class SmartPtr<T>;//定义智能指针类为友元,可以让智能指针类直接操纵辅助类 int refCount; T* pointer; RefPtr(T* ptr) :pointer(ptr), refCount(1){} ~RefPtr(){ delete pointer; } }; //智能指针类 template<typename T> class SmartPtr{ public: SmartPtr(T* realPtr); //构造函数 ~SmartPtr();//析构函数 SmartPtr(const SmartPtr& rhs); //拷贝构造函数 SmartPtr& operator=(const SmartPtr&);//拷贝赋值运算符 T* get() const; //获取原始指针 T* operator->() const;//重载->运算符 T& operator*() const;//重载*运算符 bool operator!() const;//重载!运算符 template<typename newType> operator SmartPtr<newType>();//隐式转换 int getRefCount();//获取引用计数 private: RefPtr<T>* rp;//辅助类对象指针 }; //构造函数 template<typename T> SmartPtr<T>::SmartPtr(T* realPtr) :rp(new RefPtr<T>(realPtr)){} //析构函数 template<typename T> SmartPtr<T>::~SmartPtr(){ if (--rp->refCount==0)//操作数引用次数减1,如果为0,说明没有对象被引用,删除 delete rp; } //拷贝构造函数 template<typename T> SmartPtr<T>::SmartPtr(const SmartPtr<T>& rhs):rp(rhs.rp){ ++rp->refCount;//左操作数引用次数加1 } //拷贝赋值运算符 template<typename T> SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs){ if (this == &rhs) //自赋值情况 return *this; ++rhs.rp->refCount;//右操作数引用次数加1 if (--rp->refCount == 0)//左操作数引用次数减1,如果为0,说明没有对象被引用,删除 delete rp; rp = rhs.rp; return *this; } //获取原始指针 template<typename T> T* SmartPtr<T>::get() const{ return rp->pointer; } //重载->运算符 template<typename T> T* SmartPtr<T>::operator->() const{ return rp->pointer; } //重载*运算符 template<typename T> T& SmartPtr<T>::operator*() const{ return *(rp->pointer); } //重载!运算符 template<typename T> bool SmartPtr<T>::operator!() const{ if (rp->pointer == nullptr) return true; return false; } //隐式转换 template<typename T> template<typename newType> SmartPtr<T>::operator SmartPtr<newType>(){ return SmartPtr<newType>(rp->pointer); } template<typename T> int SmartPtr<T>::getRefCount(){ return rp->refCount; } #endif //Tmb.h #ifndef TMB_H #define TMB_H #include<iostream> class Top{ public: Top(int i = 0){ iTop = i; } void printT(){ std::cout << iTop << std::endl; } private: int iTop; }; class Middle :public Top{ public: Middle(int i = 0) :Top(i){} void printM(){ printT(); } }; class Bottom :public Middle{ public: Bottom(int i = 0) :Middle(i){} void printB(){ printM(); } private: int iTop; }; #endif //main.cpp #include"Smart.h" #include"Tmb.h" #include<iostream> using namespace std; int main(){ Top* p1 = new Top(1); SmartPtr<Top> sp1(p1); cout << "此时sp1的引用计数为:" << sp1.getRefCount() << endl;// 1 SmartPtr<Top> sp2(sp1);//sp1,sp2的rp指向同一个对象 cout << "此时sp1的引用计数为:" << sp1.getRefCount() << endl;// 2 cout << "此时sp2的引用计数为:" << sp2.getRefCount() << endl;// 2 cout << "---------------------------------------" << endl; Top* p2 = new Top(2); SmartPtr<Top> sp3(p2); cout << "此时sp1的引用计数为:" << sp1.getRefCount() << endl;//2 cout << "此时sp2的引用计数为:" << sp2.getRefCount() << endl;//2 cout << "此时sp3的引用计数为:" << sp3.getRefCount() << endl;//1 cout << "---------------------------------------" << endl; sp3 = sp1;//首先sp1的引用计数加1,因为多了一个sp3指向它的对象,所以sp1的引用计数此时为3 //而sp3引用计数此时减1,变成了0,此时 p2这个内存没有人占用,所以此时释放,这个时候调用析构函数删除p2 cout << "此时sp1的引用计数为:" << sp1.getRefCount() << endl;// 3 cout << "此时sp2的引用计数为:" << sp2.getRefCount() << endl;// 3 cout << "此时sp3的引用计数为:" << sp3.getRefCount() << endl;// 3 sp1->printT(); (*sp1).printT(); system("pause"); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
posted on 2015-09-05 14:02 ruan875417 阅读(112) 评论(0) 编辑 收藏 举报