【more effective c++読書ノート】【第5章】技術(4)——Smart Pointers(スマートポインタ)
6775 ワード
一、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;
}