1. 程式人生 > >c++智慧指標類實現

c++智慧指標類實現

智慧指標(smart pointer)是儲存指向動態分配(堆)物件指標的類,用於生存期控制,能夠確保自動正確的銷燬動態分配的物件,防止懸垂指標的出現在類物件中,如果定

義一個int型的指標,當多次使用同一個已存在的物件初始化一些新建物件時,已存在的物件和新建的物件都指向同一塊記憶體區域,當我們在使用某一個物件時釋放了該記憶體空間,

那麼其它物件的int型指標域全都會失效,為了防止這種情況的產生,我們通常定義一個類,這個類裡有一個引用計數器(用來統計有多少個物件指向共享記憶體區域)和一個int型的指

那麼這塊共享區域就由該智慧指標類管理,下面是一張來自c++ primer的結構圖:


簡單實現:

/*
智慧指標類設計實現
*/
#include<iostream>  
#include<vector>  
#include<map>  
#include<fstream>
#include<sstream>  
#include<algorithm>
#include<list>
#include<cstring>
using namespace std;

class smartpointer{//定義一個智慧指標類
private:
	friend class own;
	int *p;//被管理記憶體的型別
	size_t use;//物件使用計數器
	smartpointer(int *pt) :use(1), p(pt){}
	~smartpointer(){ delete p; }
};

typedef struct t{
	smartpointer *spt;
	struct t *next;
}node;

class own{
public:
	//複製控制部分
	own(int *p,int val){
		int flag = true;
		if (link == NULL){//如果是空的話
			node *temp = new node;
			temp->spt = new smartpointer(p);
			temp->next = NULL;
			link= temp;
		}
		else{
			node *head = link;
			while (head != NULL){
				if (p ==head->spt->p){
					ptr = head->spt;
					ptr->use++;
					value = val;
					flag = false;
					break;
				}
				head=head->next;
			}
		}
		if (true){
			node *temp=new node;
			ptr = new smartpointer(p);
			temp->spt = ptr;
			temp->next = link;
			link = temp;
			value = val;
		}
	}
	own & operator=(const own &obj){
		++obj.ptr->use;
		if (--ptr->use == 0)delete ptr;
		value = obj.value;
		ptr = obj.ptr;
		return *this;
	}
	own(const own&obj){
		value = obj.value;
		ptr = obj.ptr;
		ptr->use++;//兩者指向同一個智慧指標物件
	}
	~own(){
		if (ptr->use == 0)delete ptr;
	}
	//獲取類的值
	int *get_ptr(){
		return ptr->p;
	}
	int get_value(){
		return value;
	}
	void set_ptr(int *new_ptr){//將其設定為指向一個新值的
		ptr->use--;
		if (ptr->use == 0)delete ptr;
		ptr = new smartpointer(new_ptr);

	}
	void set_val(int val){
		value = val;
	}
private:
	int value;
	smartpointer *ptr;
	static node *link ;//用來儲存已經存在的smartpoint類物件
};

node *own::link = NULL;//剛開始設為空值

int main(){
	int *p = new int[50];
	own b1(p, 1);
	own b2(p, 2);
	cout << b1.get_ptr() << endl;
	cout << b2.get_ptr() << endl;
	delete []p;
	return 0;
}
/*
以上智慧指標的實現做了如下優化:
1.當用同一塊記憶體去建立own物件時,不會新建smartpointer類
*/


其中我們用link變數將own類所有物件所指的記憶體區域連結起來,當用一個記憶體塊新建一個own物件時,我們先檢查p是否是已經新建的記憶體塊,如果是的,我們就將物件的

ptr域指向已有的smartpoint類物件,如果p不存在,我們這個時候才新建一個smartpoint類物件.