1、構造函數/默認構造函數:關於怎樣去初始化一個對象的問題,也就是一個新的數據類型怎樣去填充它的內容,需要考慮是否需要是explicit還是implicit強調,一般建議explicit來強調,因為存在隱式類型轉換總是讓人不太放心。需要考慮的細節很多,有默認參數的值設計,數據成員初始化列表等等。。。實例化一個對象也就是運行了一次相應的構造函數,保證實例化之後的對象的數據成員的內容可控總是好的。
class A
{
A();
A(X _x, Y _y):x(_x),y(_y){ }
//...
private:
X x;
Y y;
//...
};
2、拷貝構造函數/賦值函數:這裡涉及到的思考是怎樣准確復制一個對象的問題。尤其是在類當中有指針指向自由空間的資源(堆空間)的時候,這個時候更加不能依賴於由編譯器默認產生的拷貝構造函數/賦值函數,因為默認的情況是按對象的成員逐個復制的,往往會涉及到析構函數多次析構同一資源,造成的結果是未定義的!又比如智能指針的所有權的轉移的問題,甚至會出現了業務邏輯錯亂的陷阱。
一般形式是:
class A
{
A(const A& rhs);//拷貝構造函數
A & operator=(const A& rhs);//賦值函數
//...
};
這個時候,需要做的就是要頭腦清醒,為這些復制操作定義自己認為最適合的任何意義。一般來講,拷貝構造函數和賦值函數是不一樣的,根本原因就是。拷貝構造函數是去完成對未初始化的存儲區的初始化,而賦值函數是去正確處理一個結構良好的對象。通常情況下,可以對賦值函數做一些優化,策略是:防止自賦值,刪除那些舊資源,復制新數據。通常每個非靜態成員都必須復制。
3、析構函數:C++程序員第一要學會的事情就是要學會照顧好自己的程序!首先就是要管理好申請的資源,承諾自己回收不再使用的資源,C++對象模型,或者管理自定義數據類型資源的一個關鍵的模型就是析構函數,編譯器保證在對象的生命期結束的時候執行該對象的析構函數(如果沒有明確定義,那麼就幫你生成一個),這是一個語言機制
!要麼乖乖按規則辦事,要麼自己負責後果。析構函數可以認為她是酒店打掃衛生的阿姨,當你在酒店房間裡開完激情的party之後,你需要有人來幫你清理這一切,對吧?否則退房之後不管不顧,那不情況一團糟嗎?所以承諾你設計的一個良好的類,一定要有一個對應的釋放資源的機制,關鍵之一是析構函數。
class A
{
virtual ~A();
};