在c++中,如果你寫下
1 classempty;
就相當於寫下
1classempty;//
copy建構函式
5 ~empty()//
析構函式
6 empty&operator=(constempty& rhs);//
copy賦值運算子
7 };
惟有當這些函式被呼叫時,他們才會被編譯器建立出來。
下面**造成上述每個函式被建立:
1 empty e1; //default建構函式
2 empty e2(e1); //
析構函式
3 e2=e1; //
copy建構函式,copy賦值運算子
如果你設計了乙個class,其建構函式要求有實參,你就無需擔心編譯器會為你新增乙個無實參版本而覆蓋掉你的版本
1 template2classnamedobject;
10 namedobject no1("
smallest prime number
",2);
11 namedobject no2(no1);//
呼叫copy建構函式
編譯器為namedobject所生成的copy賦值運算子,其行為基本上與copy建構函式如出一轍,但一般而言只有在生出的**合法且有合適機會證明它有意義,其表現才會如先前所說。萬一條件不符,編譯器會拒絕為其生出operator=。
例如:
1 template2classnamedobject;
考慮下面會發生什麼:
1 std::string newdog("persephone");
2 std::string olddog("
satch");
3 namedobject p(newdog,2
);4 namedobject s(olddog,36
);5 p=s; //
現在p要發生什麼事?
賦值前,p.namevalue和s.namevalue都指向string物件。p該如何變化?是reference改變嗎?c++不允許讓 reference改指向不同的物件。是string物件被修改嗎?那麼將影響其他持有指標或引用而且指向該string的其他物件。對此,c++拒絕編譯那一行賦值動作。
最後還有一種情況: 如果某個基類將copy賦值運算子宣告為private,編譯器將拒絕為其派生類生成copy賦值運算子。
畢竟編譯器為派生類所生的copy賦值運算子想象中可以處理基類成分,但他們當然無法呼叫派生類無法呼叫的函式。
而如果你不想使用這些自動生成的成員函式,可以在private成員裡面宣告他們,而不提供定義。
1class
homeforsale;
有了上述class定義,當使用者企圖拷貝homeforsale物件,編譯器會阻撓他,如果你不慎在member函式或friend函式內那麼做,輪到鏈結器發出抱怨。
將鏈結期錯誤移至編譯期是可能的(而且那是好事,畢竟愈早發現錯誤愈好),只要將copy建構函式和copy賦值運算子宣告為private就可以辦到,但不是homeforsale自身,而是在乙個專門為了阻止copying動作而設計的base class非常簡單。
1class
uncopyable //
允許derived物件構造和析構
4 ~uncopyable(){}
5private
:6 uncopyable(const uncopyable&); //
但阻止copying
7 uncopyable& operator=(const uncopyable&);
8 };
條款5 了解C 默默編寫並呼叫哪些函式
這些函式包括 預設建構函式,複製建構函式,賦值建構函式,以及析構函式。這些函式都屬於public部分。但是在有些情況下,賦值建構函式時沒有意義的,此時編譯器就會拒絕構造,舉乙個例子 template class test void print cout 此時,如果你定義了3個test類的物件t1,t...
條款05 了解C 默默編寫並呼叫哪些函式
條款05 了解c 默默編寫並呼叫哪些函式 編譯器可以暗自為class建立default建構函式,copy建構函式,copy assignment操作符,以及析構函式 唯有當這些函式被呼叫,它們才會被編譯器建立出來 include include using std cout using std en...
條款5 了解C 默默編寫並呼叫哪些函式
1.empty class 在c 處理過後就不再是乙個empty class.編譯器會為它宣告乙個copy 建構函式,乙個copy assignment操作符,乙個析構函式。此外你如果你沒有宣告任何建構函式,編譯器也會為你宣告乙個default建構函式。所有這些函式都是public且inline。所...