目錄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作業,...