C++實現智慧指標(三)
阿新 • • 發佈:2019-02-06
一. 實現版本v3
- 引用計數技術:
引用計數需要儲存在被引用的資源物件裡,一個資源物件對應一個引用計數, 當其引用計數為0時,資源物件可以被銷燬。
需要修改以下函式中實現計數功能:
- 接收不同物件型別的建構函式:這個建構函式實現,比較簡單,直接將引用計數加1 即可
- 解構函式:解構函式的實現,不能再直接做delete操作,而是需要先對引用計數減1,當引用計數為0時,才做delete操作。
- 拷貝建構函式:拷貝建構函式的實現,底層指標共享,然後將引用計數加1 即可。
- 賦值操作符:賦值操作的實現,稍微複雜一些,涉及到將新指向物件的引用計數加1,將原指向物件的引用計數減1,如果有需要還要銷燬原指向物件。這裡有一點值得注意的地方,我們新的賦值操作的實現,不再需要if (this == &other) return *this;語句處理自我賦值的情況,讀者可自行分析一下我們新的賦值操作的實現為何不需要通過if語句去處理自我賦值的情況。
- 引用計數基類
一般按照面向物件的設計方法,我們會將管理引用計數的相關內容,抽象成一個基類,這樣任何期望能夠被智慧指標引用的資源類,只要繼承該類即可。
- 標頭檔案 smartpointer.h
/* * file name : smartpointer.h * desp : 智慧指標版本v3 */ #ifndef __SMARTPOINTER_H__ #define __SMARTPOINTER_H__ template <typename T> // 將智慧指標類定義成模板類 class SmartPointer { public: // 預設建構函式 SmartPointer():mPointer(NULL) {std::cout <<"Create null smart pointer."<< std::endl;} // 接收不同物件型別的建構函式 SmartPointer(T *p):mPointer(p) { std::cout <<"Create smart pointer at "<<static_cast<const void*>(p)<<std::endl; /*智慧指標指向類T,引用計數加1*/ if (mPointer) mPointer->incRefCount(); } // 解構函式 ~SmartPointer(){ std::cout << "Release smart pointer at "<<static_cast<const void*>(mPointer)<<std::endl; // 實現記憶體資源自動銷燬機制 if (mPointer && mPointer->decRefCount()==0) delete mPointer; } // 拷貝建構函式 SmartPointer(const SmartPointer &other):mPointer(other.mPointer) { std::cout <<"Copy smart pointer at "<<static_cast<const void*>(other.mPointer)<<std::endl; // 引用計數加1 if(mPointer) mPointer->incRefCount(); } // 賦值操作符 SmartPointer &operator = (const SmartPointer &other) { T *temp(other.mPointer); // 新指向物件,引用計數值加1 if (temp) temp->incRefCount(); // 原指向物件,引用計數值減1,如果減1後引用計數為0 銷燬原資源物件 if (mPointer && mPointer->decRefCount()==0) delete mPointer; // 智慧指標指向新資源物件 mPointer = temp; return *this; } private: T *mPointer; // 指向智慧指標實際對應的記憶體資源,根據引數自動推導規則,定義內部資源指標型別 }; /*引用計數基類*/ class RefBase { public: RefBase() : mCount(0){ } void incRefCount(){ mCount++; } int decRefCount(){ return --mCount; } // 除錯介面,返回物件當前引用計數 int getRefCount(){ return mCount; } virtual ~RefBase(){ } private: int mCount; }; #endif // __SMARTPOINTER_H__
- 測試檔案 sptestcase3.cpp
/*
* file name : sptestcase3.cpp
* desp : 智慧指標測試程式碼 case3 測試智慧指標的引用計數功能
*/
#include <iostream>
#include "smartpointer.h"
/*繼承於引用計數基類的SomeClass類*/
class SomeClass: public RefBase{
public:
SomeClass(){std::cout << "SomeClass default constructor !"<<std::endl;}
~SomeClass(){std::cout << "SomeClass deconstructor !"<<std::endl;}
};
void testcase3(void)
{
SomeClass *pSomeClass = new SomeClass(); //1
SmartPointer<SomeClass> spOuter = pSomeClass;
std::cout << "SomeClass Ref Count (" << pSomeClass->getRefCount() << ") outer 1."<< std::endl;
{ // inner 語句塊
SmartPointer<SomeClass> spInner = spOuter;
std::cout << "SomeClass Ref Count (" << pSomeClass->getRefCount() << ") inner."<< std::endl;
}
std::cout << "SomeClass Ref Count (" << pSomeClass->getRefCount() << ") outer 2."<< std::endl;
// delete pSomeClass ; 不需要也不能執行delete操作!
std::cout << "new another SomeClass class for spOuter."<< std::endl;
SmartPointer<SomeClass> spOuter2 = new SomeClass();
spOuter = spOuter2;// 1處new出來的SomeClass將會被自動釋放
}
int main(void)
{
testcase3();
return 0;
}
結果分析
- v3版本基本實現了智慧指標功能,下一步可完善作為指標的功能:解引用、判空、比較操作
二. 知識點查漏補缺
- 野指標