Memory (C++ 標準庫)

memory 是 C++ 標準程式庫中的一個標頭檔案，定義了 C++ 標準中的智慧指標、記憶體分配器（allocator）、與垃圾回收有關的函式、臨時性的申請與釋放動態記憶體的函式、在記憶體上建立（構造）物件的函式等等。

運算子

operator!= 測試 allocator、智慧指標是否不等
operator== 測試 allocator、智慧指標是否相等
operator>= 測試智慧指標所指向的資料物件地址
operator 測試智慧指標所指向的資料物件地址
operator

template >

class unique_ptr {

public:

typedef Type element_type; // 指標基型別

typedef Del deleter_type; // 析構型別

typedef T1 pointer; // 指標型別 為 Del::pointer，否則為 Type // 建構函式

unique_ptr ; //11 空指標

uniqueptr (nullptrt _Nptr); //22 空指標

explicit uniqueptr (pointer Ptr); //33

uniqueptr (pointer Ptr, typename conditional::value, Del,typename addreference::type>::type Deleter); //44

uniqueptr (pointer Ptr,typename removereference::type&& Deleter); //55

uniqueptr (uniqueptr&& _Right); //66

template uniqueptr (uniqueptr&& _Right); //77

// 解構函式

~unique_ptr ;

//

uniqueptr& operator= (uniqueptr&& _Right); // 右值賦值

template uniqueptr& operator= (uniqueptr&& _Right);// 右值賦值

void swap (uniqueptr& Right); // 交換兩個 unique_ptr 物件的內容

pointer release ; // 在 stored_ptr 中儲存 pointer 的新的值，並返回前一個值，用於放棄對所指資料物件的獨佔

void reset (pointer _Ptr = pointer ); //delete 當前擁有的資源並接受新的資源

pointer get const; // 返回 stored_ptr

Type& operator const; // 返回 stored_ptr

pointer operator-> const; // 返回 stored_ptr

Del& getdeleter ; // 返回 storeddeleter 的引用

const Del& getdeleter const; // 返回 storeddeleter

explicit operator bool const; //get != pointer 的值

uniqueptr (const uniqueptr& _Right) = delete;

uniqueptr& operator=(const uniqueptr& _Right) = delete;

private:

pointer stored_ptr; //exposition only

Del stored_deleter; //exposition only

};

unique_ptr 的主要用途有：

實現資源獲取即初始化（RAII）。當程式發生異常時，異常處理機制的棧展開（stack unwinding）會銷燬區域性變數，包括 unique_ptr 物件，從而自動釋放資源。
實現右值移動語義。例如，unique_ptr 型別可作為函式的返回值型別，採用了隱式地移動賦值。
在容器中儲存 unique_ptr 物件。需要顯式地移動賦值，即透過 std::move 。

1.1 shared_ptr

sharedptr 是一個類模板，包裝了使用引用計數的智慧指標。當 sharedptr 在退出其作用域、生命期結束時，解構函式或自動對所指記憶體資料物件的引用計數減去 1。如果記憶體資料物件的引用計數為 0，則會被自動 delete。指向同一資源的 sharedptr 共同擁有一個控制塊，其中儲存了 sharedptr 的引用計數、指向這一資源的 weak_ptr 的數目、資源的析構器（deleter ）地址、對該控制塊的可定製的 allocator。

template

class shared_ptr {

public:

typedef Ty element_type; // 指標基型別

// 建構函式

shared_ptr ; //11 空指標

sharedptr (nullptrt); //22 空指標

sharedptr (const sharedptr& sp); //33 複製構造

sharedptr (sharedptr&& sp); //44 右值移動構造

template explicit shared_ptr (Other * ptr); //55 由其他指標初始化，構造失敗時自動呼叫 delete ptr

template shared_ptr (Other * ptr, D dtor); //66 由其他指標初始化，dtor 是個可呼叫的函式物件，構造失敗時自動呼叫 dtor (ptr)

template sharedptr (nullptrt, D dtor); //77 空指標，並指定 deleter

template sharedptr (Other *ptr, D dtor, A alloc);//88 alloc 管理 sharedptr 控制塊的記憶體分配與釋放，構造失敗時自動呼叫 dtor (ptr)

template sharedptr (nullptrt, D dtor, A alloc);//99 空指標

template sharedptr (const sharedptr& sp); //0A 複製構造 + 型別轉換

template sharedptr (const sharedptr&& sp); //0B 移動構造 + 型別轉換

template explicit sharedptr (const weakptr& wp); //0C 由弱指標複製構造

template sharedptr (autoptr& ap); //0D 由 auto_ptr 指標複製構造

template sharedptr (uniqueptr&& up); //0E 由 unique_ptr 移動構造

template sharedptr (const sharedptr& sp, Ty *ptr); //0F

templatesharedptr (const uniqueptr& up) = delete;//10 停用 const unique_ptr 作為移動建構函式

~shared_ptr ; // 解構函式

sharedptr& operator=(const sharedptr& sp); // 賦值運算子

template sharedptr& operator=(const sharedptr& sp); // 型別轉換的賦值運算子

sharedptr& operator=(sharedptr&& sp); // 右值引用的移動語義

template sharedptr& operator=(sharedptr&& sp); // 右值引用 + 型別轉換

template sharedptr& operator=(autoptr&& ap); // 右值引用 + auto_ptr 型別轉換

template sharedptr& operator=(const uniqueptr& up) = delete; // 禁止 const 型 uniqueptr 移動賦值給 sharedptr

template sharedptr& operator=(uniqueptr&& up);// 右值引用的移動語義 + 型別轉換

void swap (shared_ptr& sp); // 交換兩個指標的內容

//reset 成員函式，把當前指向的資料物件的引用計數減 1，然後指向引數表中新的資料物件

void reset ;

template void reset (Other *ptr);

template void reset (Other *ptr, D dtor);

template void reset (Other *ptr, D dtor, A alloc);

Ty *get const; // 返回所指向的資料物件的地址

Ty& operator* const; // 返回所指向的資料物件

Ty *operator-> const; // 返回所指向的資料物件的地址

long use_count const; // 返回引用計數值

bool unique const; // 判斷是否獨佔引用資料物件

operator bool const; // 判斷是否指向了一個數據物件

template bool ownerbefore (sharedptr const& ptr) const;

template bool ownerbefore (weakptr const& ptr) const;

template D* getdeleter (sharedptr const& ptr);

};

1.2 weak_ptr

弱指標 weakptr 用於指向、但不擁有（即不參加引用計數）由 sharedptr 管理的資源。弱指標並不直接提供對資源的訪問。應該透過 sharedptr 來訪問資源。當資源的引用計數為 0（所有擁有該資源的 sharedptr 物件都已被銷燬），該資源將被 delete，這時如果仍然有弱指標指向該資源，則該弱指標將變為 expired 狀態。這實際上避免了資源的迴圈引用計數。對於迴圈的引用計數，如果把其中的一個 sharedptr 的指標指向改為 weakptr 的指標指向，即打破了迴圈引用。

template class weak_ptr {

public:

typedef Ty element_type; // 指標基型別

// 建構函式

weak_ptr ; // 空指標

weakptr (const weakptr&); // 複製構造

template weakptr (const weakptr&); // 型別轉換的複製構造

template weakptr (const sharedptr&); // 從 shared_ptr 複製構造

// 賦值運算子

weakptr& operator=(const weakptr&);

template weakptr& operator=(const weakptr&);

template weakptr& operator=(sharedptr&);

void swap (weak_ptr&); // 交換物件的內容

void reset ; // 放棄指向資源，當前物件變為空的弱指標

long use_count const; // 返回資源的引用計數

bool expired const; // 判斷指向的資源是否還存在（或已經被釋放）

shared_ptr lock const; // 獲取對資源的專屬擁有};

1.3 auto_ptr

auto_ptr，即自動指標，在 C++11 標準是過時的類模板。

函式

void align (std::sizet alignment,std::sizet size,void& ptr,std::size_t& space); 在一塊記憶體（ptr 所指）中，按照對齊要求 slignment，找到一塊長度為 size 的，並重置 ptr 為該記憶體起始地址，space 為該記憶體長度。
allocateshared 這是 sharedptr 的工廠函式，指定記憶體分配器 allocator 與資料物件的初始化引數，建立資料物件及 shared_ptr。
constpointercast 用於 shared_ptr 物件的 const 的型別轉換。
declarenopointers 用於垃圾回收。告知垃圾收集器在指定的記憶體範圍內不含可跟蹤的指標。
declarereachable 用於垃圾回收。令垃圾收集器知道引數指標是指向一塊宣告為可達的動態分配記憶體。宣告為可達的（declared reachable）完全物件，是指該物件作為形參所指，declarereachable 呼叫的次數超過 undeclare_reachable 呼叫次數。宣告為可達的一塊動態分配記憶體不能被垃圾收集器釋放，即使它看起來沒有可達的訪問方法。
dynamicpointercast 對 shared_ptr 物件的執行時動態轉換型別。
getdeleter 返回 sharedptr 物件的 deleter。
getpointersafety 用於垃圾回收。返回當前的垃圾回收器採用的指標型別。
gettemporarybuffer 對給定型別、給定物件數目，分配一塊臨時的記憶體儲存。
makeshared 這是 sharedptr 的工廠函式，使用給定的資料物件的初始化引數，建立資料物件及 shared_ptr。
ownerless 混合比較 sharedptr 物件與 weak_ptr 物件的序關係。
pointersafety 用於垃圾回收。是 getpointer_safety 的返回值的列舉型別。
returntemporarybuffer 釋放由 gettemporarybuffer 分配的臨時性的記憶體塊。
staticpointercast 編譯時靜態轉換 shared_ptr 的值型別。
swap 交換兩個 sharedptr 物件或交換兩個 weakptr 物件.

undeclarenopointers 用於垃圾回收。告訴垃圾回收器，在指定範圍的記憶體中，存著可跟蹤指標。
undeclarereachable 用於垃圾回收。告訴垃圾回收器，被形參指標所指的動態分配記憶體塊，撤銷一次 declarereachable 操作。如果動態分配記憶體塊上沒有 declare_reachable 操作，則垃圾收集器如果判斷它已經是不可達的狀態（即沒有手段訪問這塊記憶體）就可把它當垃圾回收。
uninitialized_copy 把輸入 iterator 所給出的一個記憶體範圍內的物件陣列的每個元素，逐個複製構造到前向的目標 iterator 所指的記憶體上。
uninitializedcopyn 把輸入 iterator 所給出的一個記憶體地址開始的物件陣列的 n 個元素，逐個複製構造到前向的目標 iterator 所指的記憶體上。
uninitialized_fill 在輸入 iterator 所給出的一個記憶體範圍內，用給定的物件去複製構造多個物件。
uninitializedfilln 在輸入 iterator 所給出的一個記憶體開始地址處，用給定的物件去複製構造指定的 n 個物件。

例子

4.1 共享指標

include

class Test

{

public:

Test

{std::cout p1 = std::make_shared ;

std::cout p2 = p1;

std::cout

4.2 弱指標例子

include

class TestB;

class TestA

{

public:

TestA

{std::cout test_ptr)

{mTestBPtr = test_ptr;}

void TestWork

{std::cout mTestBPtr;};

class TestB

{

public:

TestB

{std::cout test_ptr)

{mTestAPtr = test_ptr;}

void TestWork

{std::cout tmp = mTestAPtr.lock ;

tmp->TestWork ;

std::cout mTestAPtr;

};

int main

{std::sharedptr ptra = std::make_shared ;

std::sharedptr ptrb = std::make_shared ;

ptra->ReferTestB (ptrb);

ptrb->ReferTestB (ptra);

std::cout

4.3 獨佔指標的例子

include

int main

{

std::unique_ptr pInt;

pInt.reset (new int );

int *p = pInt.release ; // 釋放所有權

// 由於 uniqueptr 有 std::uniqueptr 的過載函式，所以它可以用來管理陣列資源

std::unique_ptr pArray (new int3 {1,3,3});

}