シンプルなスマートポインタを実現

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の本の上で参考にした)は、いくつかの比較的に巧みな地方があります
  • Has_Ptrというクラスは実はint*のポインタを保存したいのですが、懸垂ポインタの出現を避けるためにI_を使いましたPointerという類は懸垂針を包んだのでHas_PtrというクラスのPublicインタフェースにはI_は現れませんポイント、int*
  • しか現れません
  • 実際にはI_も現れませんPointer、Pointerのコンストラクション関数はPrivateと定義されているため、外部でのコンストラクションは許可されず、friendクラスでのみコンストラクションでき、I_PointerはHas専用ですPtr実装の
  • 三元グループ(コピー構造、賦値操作、析構)を覚え、そのうちの1つが特殊な操作を必要とする場合、他のものも特殊な操作を必要とし、これは定勢思考を形成しなければならない.