1. 程式人生 > >shared_ptr智慧指標的簡單實現

shared_ptr智慧指標的簡單實現

shared_ptr是一種智慧指標資料結構,除了具有智慧指標的基本功能——自動管理資源釋放外,還有一個特徵就是"share",我理解所謂的“share”就是多個shared_ptr共同分享同一處資源,避免了資源的拷貝。比如,當執行拷貝建構函式操作時:

class X{...};

shared_ptr<X> px1(new X());
shared_ptr<X> px2(px1);

或是賦值操作時:

class X{...};

shared_ptr<X> px1(new X(...));
shared_ptr<X> px2(new X(...));
px2 = px1;

shared_ptr不進行資源的拷貝,而是將內部的指標指向相應的資源即可。以上例子中,px2並不會從px1中拷貝資源,而是將內部指標指向px1中的資源。

那麼px2或px1被銷燬時會發生什麼?會將其指向的內部資源同時銷燬嗎?不會。現在的資源是大家公用的,不能被隨意銷燬。shared_ptr是採用引用計數(reference counting)來控制資源的指向和銷燬。內部資源會伴有一個計數值count,count表示有多少個shared_ptr指向該資源,每當有一個新的shared_ptr指向該資源時,count值加1,當有一個指向該資源的shared_ptr銷燬時,count值減1,當count變為0時,證明所有指向該資源的shared_ptr已經銷燬,此時內部資源也被銷燬。

自己寫了一個簡單的shared_ptr模板類,如下:

template<class T>
class my_shared_ptr{
public:
	my_shared_ptr(T* pt){
		_pBlock = new ControlBlock(pt);
	}
	my_shared_ptr(const my_shared_ptr& rhs){
		_pBlock = rhs._pBlock;
		_pBlock->ref_count++;
	}
	~my_shared_ptr(){
		_pBlock->ref_count --;
		if(0 == _pBlock->ref_count)
			delete _pBlock;
	}
	my_shared_ptr& operator=(const my_shared_ptr& rhs){
		if(this == &rhs)
			return *this;

		_pBlock->ref_count --;
		if(0 == _pBlock->ref_count)
			delete _pBlock;

		_pBlock = rhs._pBlock;
		_pBlock->ref_count++;
	}

	T* get(){return _pBlock->_ptr;}
	T* operator->(){return _pBlock->_ptr;}
	void reset(T* pt){
		_pBlock->ref_count --;
		if(0 == _pBlock->ref_count)
			delete _pBlock;

		_pBlock = new ControlBlock(pt);
	}

private:
	struct ControlBlock{
		int ref_count;
		T* _ptr;
		ControlBlock(T* pt){
			_ptr = pt;
			ref_count = 1;
		}
		~ControlBlock(){
			delete _ptr;
		}
	};
	ControlBlock* _pBlock;
};

my_shared_ptr內部有一個ControlBlock管理內部資源,同時有一個計數值ref_count標記指向該內部資源的my_shared_ptr個數。在拷貝建構函式和賦值操作符中,都有:

_pBlock = rhs._pBlock;
_pBlock->ref_count++;

語句,這兩句表示當發生my_shared_ptr的拷貝時,不拷貝內部資源,而是將內部指標指向同樣的內部資源,並增加計數值。

在解構函式中可以看到如下語句:

_pBlock->ref_count --;
if(0 == _pBlock->ref_count)
	delete _pBlock;

表示內部資源不是隨意銷燬的,解構函式會減小計數值,當計數值變為0時,內部資源才會銷燬。
在賦值操作符函式中,首先進行自檢,其次釋放本身指向的內部資源,之後指向新的內部資源,並更新計數值。

測試程式如下:

#include "my_shared_ptr.h"
#include <iostream>
using namespace std;

class X{
public:
	X(int i):_val(i){
		cout << "X(" << _val << ") constructed." << endl;
	}
	~X(){
		cout << "X(" << _val << ") destructed." << endl;
	}
	void print(){
		cout << "X(" << _val << ")::print()." << endl;
	}
private:
	int _val;
};


int main(){

	my_shared_ptr<X> shared_px1(new X(10));
	my_shared_ptr<X> shared_px2(new X(20));

	shared_px1->print();
	shared_px2->print();

	shared_px2 = shared_px1;

	shared_px1->print();
	shared_px2->print();
}

執行結果如下:

X(10) constructed.
X(20) constructed.
X(10)::print().
X(20)::print().
X(20) destructed.
X(10)::print().
X(10)::print().
X(10) destructed.

可以看到,在執行賦值操作符函式後,shared_px2所指向的內部資源被銷燬, 因為X(20)被析構;之後shard_px2和shared_px1指向了同一個內部資源,因為都列印了X(10)::print(). 程式結束時,所有內部資源都被自動銷燬。

相關推薦

C++智慧指標簡單實現

#include <iostream> #include <string> #include <vector> #include <list> namespace smart_pointer { // RAII(Resou

shared_ptr智慧指標簡單實現

shared_ptr是一種智慧指標資料結構,除了具有智慧指標的基本功能——自動管理資源釋放外,還有一個特徵就是"share",我理解所謂的“share”就是多個shared_ptr共同分享同一處資源,避免了資源的拷貝。比如,當執行拷貝建構函式操作時: class X{...

智慧指標shared_ptr)的簡單實現

1、原理: shared_ptr允許拷貝和賦值,其底層實現是以"引用計數"為基礎的,通過引用計數來控制空間的釋放,每一個shared_ptr的拷貝都指向相同的記憶體。當有新的指標指向這塊空間時,內部的引用計數加1,每析構一次,內部的引用計數減1,直到引用計數減為0時自動刪除

簡單智慧指標實現

直上程式碼,大佬忽略 #include <iostream> #include <string> using namespace std; //定義智慧指標模板類 template<typename T> class SmartP

一個簡單智慧指標實現

#include<iostream> #include<memory> using namespace std; template<typename T> cla

C++智慧指標簡單剖析

導讀 《C++ Primer Plus》第六版,其中關於智慧指標的章節解析的非常清晰。C++面試過程中,很多面試官都喜歡問智慧指標相關的 問題,比如你知道哪些智慧指標?shared_ptr的設計原理是什麼?如果讓你自己設計一個智慧指標,你如何完成?等等……。而且在看開源的C

智慧指標實現

1 智慧指標 智慧實現需要實現的功能: 指標生命週期結束後主動釋放堆空間 一片堆空間最多隻能由一個指標標識 杜絕指標運算和指標比較(不過載相關的操作符即可) 2 程式碼實現 實現檔案:SmartPointer.h #ifndef SMARTPOINTER_

一個智慧指標實現

1.什麼是智慧指標? C++智慧指標是行為類似於指標的類物件。它使用設計模式中的代理模式,代理了原始“裸”指標的行為,為指標添加了更多更有用的特性。C++引入異常機制後,智慧指標由一種技巧升級為一種非常重要的技術,因為如果沒有智慧指標程式設計師必須保證new物件能在正確的時

C++過載——智慧指標實現

本文參照於狄泰軟體學院,唐佐林老師的——《C++深度剖析教程》 智慧指標背後的設計思想 在專案開發中,有一個臭名昭著的BUG——記憶體洩漏。不管是新手還是老手都容易犯這個錯誤。並且這種BUG很難查詢。 1. 編譯器並不能發現記憶體洩漏的問題。 2

c++智慧指標實現

智慧指標(smart pointer)是儲存指向動態分配(堆)物件指標的類,用於生存期控制,能夠確保自動正確的銷燬動態分配的物件,防止懸垂指標的出現。在類物件中,如果定 義一個int型的指標,當多次使用同一個已存在的物件初始化一些新建物件時,已存在的物件和新建的物件都指向同

智慧家居簡單實現---使用ESP8266簡單實現和APP通訊

轉載於:http://blog.csdn.net/jsagacity/article/details/78531819 前段時間,公司利用 ESP8266 這個WiFi模組,做了好多小產品。從手機 APP 直連這個 ESP8266 進行通訊,再到實現遠端控制。中間實現過程

c++ shared_ptr智慧指標使用注意事項

#include <boost/make_shared.hpp> #include <vector> using namespace std; using namespace boost; int main (int argc, const char * argv[]) {

智慧指標shared_ptr簡單實現

#include<iostream> using namespace std; class U_Ptr {friend class HasPtr;int *ip;size_t use;U_Ptr(int *p) :ip(p), use(1){cout <&

C++之智慧指標std::shared_ptr簡單使用和理解

1  智慧指標std::shared_ptr相關知識和如何使用 我們這裡先說下智慧指標std::shared_ptr,因為我看到我我們專案c++程式碼裡面用得很多,我不是不會,所以記錄學習下 先讓ubuntu終端支援c++11,如果自己的電腦還沒配置號,可以先看下我的這篇部落格

智慧指標shared_ptr實現

#include <iostream> using namespace std; template <class T> class smart { public: smart() = default; smart(T* ptr = nullptr):_ptr(

智慧指標shared_ptr實現

1.實現原理:shared_ptr是利用一個計數器,無論我們使用拷貝建構函式、賦值運算子過載、作為函式返回值、或作為引數傳給一個引數時計數器+1, 當shared_ptr被賦予一個新值或者需要銷燬時,計數器–,直到計數器為0時,呼叫解構函式,釋放物件,並銷燬其記憶體。shaerd_ptr

[學習操練]C++智慧指標類的簡單實現(類模板實現

問題的提出 在使用指標的過程中,我們有時需要動態的分配指標,在c++中,我們推薦使用new分配記憶體,delete釋放記憶體。在編寫大型程式的時候,有時我們忘記delete分配的記憶體,或者多次釋放分配的記憶體,這樣會造成記憶體洩露和程式的down機。 解決方案 在程式開發中

C++ 引用計數技術及智慧指標簡單實現

一直以來都對智慧指標一知半解,看C++Primer中也講的不夠清晰明白(大概是我功力不夠吧)。最近花了點時間認真看了智慧指標,特地來寫這篇文章。 1.智慧指標是什麼 簡單來說,智慧指標是一個類,它對普通指標進行封裝,使智慧指標類物件具有普通指標型別一樣的操作。具體而言,複製物件時,副本和原物件都指向同一儲存

c++智慧指標簡單實現

為了管理具有指標成員的類,必須定義三個拷貝控制成員函式:拷貝建構函式、operato=、解構函式。這些成員可以定義指標成員的指標型子行為或之行為。 智慧指標是行為類似於指標的的類物件,智慧指標在物件間共

C++ 幾種智慧指標簡單實現

#pragma once// 智慧指標 // 定義個類來封裝資源的分配和釋放,在構造 函式完成資源的分配和初始化,在解構函式完成資源的// 清理,可以 保證資源的正確初始化和釋放。// 這裡簡單實現 AutoPtr、 ScopedPtr、ScopedArray以及 Share