一幕袱、Big Three:拷貝構造函數(shù),拷貝賦值函數(shù)围小,析構函數(shù)
1.拷貝構造函數(shù)
文字定義:拷貝構造函數(shù),又稱復制構造函數(shù)树碱,是一種特殊的構造函數(shù)肯适,它由編譯器調用來完成一些基于同一類的其他對象的構建及初始化。其唯一的形參必須是引用成榜,但并不限制為const框舔,一般普遍的會加上const限制。
形式定義:string(const string& str);
調用形式:string s1("hello");
? ? ? ? ? ? ? ? string s2(s1);//這里調用赎婚,在構造階段
? ? ? ? ? ? ? ? string s2 = s1;//和上面完全一樣
2.拷貝賦值函數(shù)
文字定義:當兩個對象之間相互賦值的時候調用刘绣,使左值對象拷貝一份右值對象的的數(shù)據(jù)并覆蓋左值對象原來的數(shù)據(jù)。
形式定義:string operator= (const string& str) ;
調用形式:string s1("hello");
? ? ? ? ? ? ? ? string s2;
? ? ? ? ? ? ? ? s2 = s1;//這里調用挣输,不構造纬凤,原對象已經(jīng)存在
3.析構函數(shù)
文字定義:析構函數(shù)(destructor) 與構造函數(shù)相反,當對象結束其生命周期時(例如對象所在的函數(shù)已調用完畢)撩嚼,系統(tǒng)自動執(zhí)行析構函數(shù)停士。
形式定義:~string();
調用形式:string *s = new string("hello");
? ? ? ? ? ? ? ? delete s;//這里調用
注意:一定要在operator=中檢測自我賦值!M昀觥恋技!
二、堆逻族、棧與內存管理
定義:
生命周期:
stack object會在其作用域(scope)結束之際結束蜻底,這種作用域內的object,又被稱為auto object瓷耙,因為它會被自動清理朱躺。
static object的生命在作用域結束之后仍然存在,直至程序結束搁痛。
global object的生命也是直至程序結束长搀。
heap object的生命是在當它顯示地調用new時,誕生鸡典,顯示地調用delete的時候源请,結束。若調了new卻不調delete,會造成內存泄漏谁尸。
關于new:
會經(jīng)歷:分配內存->強制類型轉換->調用構造函數(shù)舅踪。
無指針類complex:
有指針類string:
關于delete []:
會經(jīng)歷:調用析構函數(shù)->delete函數(shù)釋放該對象本身的空間。一般在析構函數(shù)中完成該對象指向的別處的空間良蛮。
無指針類complex:
有指針類string:
內存分配塊:
調試模式下:首尾:2個cookie ? ? ? ?調試模式下的占用:32+4 ? ? ? ? 數(shù)據(jù):4*2
以上合計52個字節(jié)抽碌。由于要保持與計算機尋址對齊,這里字符填充為16的倍數(shù)决瞳,即64個字節(jié)货徙。
41中的4就表示64個字節(jié),41中的1表示這片內存被占用著皮胡。
其它分析同理痴颊。
單獨new:
array new:
調試模式下:首尾:2個cookie ? ? ? ?debugger header占用:32+4? ? ? ? 數(shù)據(jù):8*3 ? ??
數(shù)組大小指示:4(下面的3)
合計72字節(jié),對齊后變成80字節(jié)屡贺。51h的5代表80個字節(jié)數(shù)蠢棱,1代表這塊空間被占用著。
注意:array new一定要搭配array delete
三甩栈、string的實現(xiàn)
四泻仙、類模板,函數(shù)模板及其它
static:
一個使用static數(shù)據(jù)成員的例子:銀行利率
單例模式的例子:
另一種寫法:
類模板:
template<typename T>
這里定義一個復數(shù)類......
complex<int> c1(2.5, 1.5);
complex<double> c2(2, 5);
函數(shù)模板:
namespace std//可能是多個地方糅合到一起的谤职。
{
...
}
其它細節(jié):
五饰豺、組合亿鲜、委托與繼承
1.組合(composition)
定義:在一個類中以另一個類的對象作為數(shù)據(jù)成員的允蜈,稱為類的組合(composition)
替換掉上面默認的模板參數(shù)后變成:
一個組合的空間大小分析:
Adapter設計模式:
現(xiàn)在需要的功能已經(jīng)有完整的實現(xiàn)了,只是名稱和接口不一樣蒿柳,重新寫一個改造一下就行了饶套。這個就叫改造器(Adapter)。
組合構造析構順序:
組合當中的構造先后順序:由內而外垒探,先構造組合對象妓蛮,再構造自己。
組合當中的析構先后順序:以外而內圾叼,先析構自己蛤克,再析構組合對象。
2.委托(delegation):composition by reference
編譯防火墻:
左邊的內容不用變夷蚊,不用再次編譯构挤,右邊的內容可以變。
注意點:
引用計數(shù)(reference counting)
n那里是一塊共享內存惕鼓,a,b,c不要輕易把控全局筋现。
當a,b,c需要改變內容時,單獨給它拷貝一份,另外兩個繼續(xù)共享矾飞。這個叫copy on write.
3.繼承(inheritance)
繼承:通過繼承機制一膨,可以利用已有的數(shù)據(jù)類型來定義新的數(shù)據(jù)類型。所定義的新的數(shù)據(jù)類型不僅擁有新定義的成員洒沦,而且還同時擁有舊的成員豹绪。我們稱已存在的用來派生新類的類為基類,又稱為父類申眼。由已存在的類派生出的新類稱為派生類森篷,又稱為子類。
繼承的三種方式:
公有繼承(public):公有繼承的特點是基類的公有成員和保護成員作為派生類的成員時豺型,它們都保持原有的狀態(tài)仲智,而基類的私有成員仍然是私有的,不能被這個派生類的子類所訪問姻氨。
在公有繼承時钓辆,派生類的對象可以訪問基類中的公有成員;派生類的成員函數(shù)可以訪問基類中的公有成員和保護成員肴焊。這里前联,一定要區(qū)分清楚派生類的對象和派生類中的成員函數(shù)對基類的訪問是不同的。
protect:保護繼承的特點是基類的所有公有成員和保護成員都成為派生類的保護成員娶眷,并且只能被它的派生類成員函數(shù)或友元訪問似嗤,基類的私有成員仍然是私有的。
這種繼承方式與私有繼承方式的情況相同届宠。兩者的區(qū)別僅在于對派生類的成員而言烁落,對基類成員有不同的可見性。
private:私有繼承的特點是基類的公有成員和保護成員都作為派生類的私有成員豌注,并且不能被這個派生類的子類所訪問伤塌。
在私有繼承時,基類的成員只能由派生類中的成員函數(shù)訪問轧铁,而且無法再往下繼承每聪。
繼承的構造析構順序:
繼承的構造順序:由內而外,先父類再子類齿风。
繼承的析構順序:由外而內药薯,先子類再父類。
注意:父類的析構函數(shù)最好寫成virtual救斑。
六童本、虛函數(shù)和多態(tài)
1.虛函數(shù)(virtual):
template method設計模式:
寫好固定的部分(Application framework),留出自己實現(xiàn)的部分系谐。