シンプルなスマートポインタを実現
2244 ワード
// helloworld.cpp : 。
//
#include "stdafx.h"
#include<iostream>
using namespace std;
//
class I_Pointer{
private:
int ref_count;
int *p;
I_Pointer(int *p): p(p), ref_count(1){}; //
~I_Pointer(){
cout<<"Delete shared pointer"<<endl;
}
friend
class Has_Ptr;
};
//
class Has_Ptr{
private:
I_Pointer *ptr; //
//
void release_ref_count(){
cout<<"release reference count"<<endl;
if(--(ptr->ref_count) == 1){
free_and_nil();
}
}
//
void add_ref(){
cout<<"add reference count"<<endl;
++(ptr->ref_count);
}
//
void free_and_nil(){
delete ptr;
ptr = NULL;
}
public:
// int
Has_Ptr(int *ptr): ptr(new I_Pointer(ptr)) {
add_ref();
}
Has_Ptr(){} //
Has_Ptr(const Has_Ptr &rhs){ //
memcpy(this, &rhs, sizeof(rhs));
add_ref();
}
~Has_Ptr(){
release_ref_count();
}
//
Has_Ptr &operator=(const Has_Ptr &rhs){
// 1
release_ref_count();
memcpy(this, &rhs, sizeof(&rhs));
// 1
add_ref();
return *this;
}
void set_ptr(int *ptr){
if (ptr != (this->ptr->p)){
this->ptr->p = ptr;
}
}
int* get_ptr(){
return ptr->p;
}
};
void test(){
int i = 0;
Has_Ptr hp(&i);
int j = 1;
Has_Ptr hp1(&j);
hp1 = hp;
}
int _tmain(int argc, _TCHAR* argv[])
{
test();
return 0;
}
1つのクラスのメンバーにポインタがある場合、デフォルトのコピーコンストラクタを使用すると、複数のオブジェクトが同じメモリを管理します.
これにより、いずれかのオブジェクトがこのメモリを解放すると、他のオブジェクトがこのメモリを操作したときに予想外の結果が発生します.
オブジェクトに野ポインタを保存することによるエラーを回避するために,複数のオブジェクト共有メモリの自己解放を実現できるスマートポインタを提案した.
実はこの実装はdelphiのインタフェースに似ていて、あちこちから伝わってきて、最後に自己解放します.インタフェースには参照カウントがあるので、参照カウントが1のときにオブジェクトを解放します.
C++の中でこのような実現(C++Primerの本の上で参考にした)は、いくつかの比較的に巧みな地方があります