每乙個class都會有乙個或多個建構函式、乙個析構函式、乙個copy assignment操作符。這些控制著基礎操作,像是產出新物件並確保它被初始化、擺脫舊物件並確保它被適當清理、以及賦予物件新值。
那麼當你當你編寫了乙個empty class的時候,當你利用編譯器的對**進行處理的時候,它其實已經並非是乙個empty class 了。編譯器會悄悄的給你生成了default 建構函式、乙個析構函式、乙個copy建構函式和乙個copy assignment操作符,並且它們都是inline的(隱式inline)。如下**示例
乙個自定類: class empty{};
其實等於以下**:
class empty //default 建構函式~empty() //析構函式
empty(const empty& rhs) //copy建構函式
empty& operator=(const empty& rhs) //copy assignment操作符
};
注意:上面的過載的操作運算子operator=的返回值是物件的引用,條款21似乎說了不要妄想返回物件的引用,這篇文章的意思不是說不能返回物件的引用,而是當你要返回物件的引用的時候,要確定引用的本體是誰,它能否被合理的delete。
那麼這四個名詞的概念分別是:
default 建構函式:在你不提供任何建構函式的情況下,系統給出的乙個不帶引數,不包含函式**的建構函式;但是當你宣告了乙個建構函式,編譯器就不再為它建立default建構函式了。
析構函式:與建構函式相反,當物件脫離其作用域時(例如物件所在的函式已呼叫完畢),系統自動執行析構函式。析構函式往往用來做「清理善後」 的工作(例如在建立物件時用new開闢了一片記憶體空間,應在退出前在析構函式中用delete釋放)。
copy建構函式:只有單個形參,而且該形參是對本類型別物件的引用(常用const修飾),這樣的建構函式成為建構函式(c++ pirmer定義)。經常被稱作x(const x&),而且也是由編譯自動呼叫。
copy assignment操作符:自動合成的一種賦值操作符。
什麼時候會呼叫copy建構函式
以下三種情況出現時,會呼叫乙個類的拷貝建構函式:
1) 用乙個已經例項化了的該類物件,去例項化該類的另外乙個物件;
2) 用該類的物件傳值的方式作為乙個函式的引數;
3) 乙個函式返回值為該類的乙個物件。
編譯器在copy建構函式被需要(被呼叫),copy建構函式才會被編譯器建立出來,但是注意,編譯器產出的析構函式是個non-virtual,除非這個class的base class自身宣告有virtual析構函式(這種情況下這個函式是虛屬性)。
什麼時候不會自動呼叫copy assignment操作符?
至於copy建構函式和copy assignment操作符,編譯器建立的版本只是單純地將**物件的每乙個non-static成員變數拷貝到目標物件。但在某些情況下編譯器拒絕生成copy assignment操作符函式。比如存在引用成員和const成員。對於引用的改變,也就是說引用自身可被改動嗎?如果是,那麼就違背了c++的原則:引用不能修改指向物件。所以必須自己定義copy assignment操作符。但是對於copy建構函式,沒有這方面的擔心,因為物件裡的引用或者const成員還沒有被初始化。比如如下**:
#include using namespace std;class person
private:
const int id;
string& name;
};
int main()
還有一種情況編譯器不會生成copy assignment函式,就是基類將copy assignment宣告為private,派生型別就無法獲得編譯器的幫助,因為編譯器為derived classes所生成的copy assignment操作符要處理base class成分。因為派生型別無法呼叫基型別的copy assignment函式(不具備訪問許可權)。
#include using namespace std;class baseclass
};class derived : public baseclass ;
int main()
所以,請記住:
編譯器可以暗自為class建立default建構函式,copy建構函式,copy assignment操作符,以及析構函式。
條款05 了解C 默默編寫並呼叫哪些函式
條款05 了解c 默默編寫並呼叫哪些函式 編譯器可以暗自為class建立default建構函式,copy建構函式,copy assignment操作符,以及析構函式 唯有當這些函式被呼叫,它們才會被編譯器建立出來 include include using std cout using std en...
條款05 了解C 默默編寫並呼叫哪些函式
什麼時候乙個空類,不再是空類了呢?當c 編譯器處理之後。如果沒有定義,編譯器會為你產生四個函式 1 預設建構函式 2 copy建構函式 3 賦值建構函式 4 析構函式 注意這些函式都是public且是inline的。這裡還有一點要說明的 不是說編譯器一定會為你產生這些函式,而是說,當這些函式被呼叫時...
條款05 了解C 默默編寫並呼叫哪些函式
什麼時候empty class 空類 不再是個empty呢?當c 處理過它之後。如果你定義類的時候自己沒有宣告,編譯器就會為它宣告 編譯器版本的 乙個copy建構函式 乙個copy assignment操作符和乙個析構函式。如果你沒有宣告任何建構函式,編譯器也會為你宣告乙個default建構函式。所...