13 2 c 拷貝控制和資源管理

2022-09-28 23:27:16 字數 2015 閱讀 4986

目錄13.2.2 定義行為像指標的類

為了定義這些成員,我們首先必須確定此型別物件的拷貝語義。一般來說,有兩種選擇:可以定義拷貝操作,使類的行為看起來像乙個值或者像乙個指標。

類的行為像乙個,意味著它應該也有自己的狀態。當我們拷貝乙個像值的物件時,副本和原物件是完全獨立的。改變副本不會對原物件有任何影響,反之亦然。

行為像指標的類則共享狀態。當我們拷貝乙個這種類的物件時,副本和原物件使用相同的底層資料。改變副本也會改變原物件,反之亦然。

定義乙個hasptr類,該類需要

hasptr的類值版本如下:

class hasptr

//對於ps指向的string,每個hasptr都有自己的拷貝

hasptr(const hasptr &p):

ps(new string(*p.ps)), i(p.i){}

hasptr& operator=(const hasptr &p);

~hasptr() //記得釋放記憶體

private:

string *ps;

int i;

};

賦值運算子組合了析構函式和建構函式的操作

這些操作需要以正確的順序執行

先拷貝右側物件

釋放左側物件的資源

更新左側物件

hasptr& hasptr::operator=(const hasptr &rhs)
在定義賦值運算子時要注意兩點:

如果操作順序錯誤,先銷毀左側物件再拷貝,就無法處理自賦值

需要定義拷貝建構函式和拷貝運算子,拷貝指標而不是string

析構函式要釋放string,在本例中,只有當最後乙個指向string的ps被銷毀後才能釋放底層string的記憶體,需要用到shared_ptr

使用shared_ptr的關鍵作用之一是引用計數,記錄指向物件的指標有多少個,在此我們不直接使用shared_ptr,而是自主實現引用計數,加強理解

工作方式

在**存放計數器?

不能作為類的成員

hasptr p1("hi");

hasptr p2(p1);

hasptr p3(p1);

建立p3時,我們可以遞增p1的計數器並把它拷貝到p3中,但是,p2的計數器沒有變化所以:要讓所有物件共享計數器的底層資料,需要把計數器定義在動態記憶體中

指標版本的hasptr

class hasptr

//拷貝建構函式拷貝所有成員,計數器+1

hasptr(const hasptr &p) :

ps(p.ps), i(p.i), use(p.use)

hasptr& operator=(const hasptr&);

~hasptr();

private :

string *ps;

int i;

int *use; //記錄有多少個共享*ps的物件

};//析構函式

hasptr::~hasptr()

}//拷貝賦值

hasptr& hasptr::operator=(const hasptr& rhs)

ps = rhs.ps; //更新左側資料

i = rhs.i;

use = rhs.use;

return *this; //返回本物件

}

足跡C primer 43 拷貝控制和資源管理

拷貝控制和資源管理 定義乙個拷貝建構函式,完成string的拷貝,而不是拷貝指標 定義乙個析構函式來釋放string 定義乙個拷貝賦值運算子來釋放物件當前的string,並從右側運算物件拷貝string class hasptr 對ps指向的string,每個hasptr物件都有自己的拷貝 hasp...

C 資源管理之 RAII

raii,它是 r esource acquisition is initialization 的首字母縮寫。也稱為 資源獲取就是初始化 是c 等程式語言常用的管理資源 避免記憶體洩露的方法。它保證在任何情況下,使用物件時先構造物件,最後析構物件。raii的好處在於它提供了一種資源自動管理的方式,當...

YARN資源管理和排程簡介

1 執行在yarn上的mapreduce應用程式 2 執行在yarn上的storm應用程式 3 yarn應用程式基本構成 客戶端 4 以mapreduce應用程式為例 mapreduce客戶端 將mapreduce作業提交到yarn上 查詢mapreduce作業執行狀態 管理mapreduce作業,...