第二周
七、三大函數(shù)
1.三大函數(shù)
Class without pointer member-complex
Class with pointer member-string
拷貝構(gòu)造 String s3(s1)
拷貝賦值 s3=s2
如果沒有寫拷貝構(gòu)造和拷貝賦值横漏,編譯器會(huì)給一套差牛,一個(gè)位一個(gè)位復(fù)制央星。如果編譯器給的夠用,不用寫,比如前面的complex滩愁。帶指針的類不能用編譯器給的默認(rèn)版本虫给,要自己寫藤抡。
除了構(gòu)造函數(shù),還有三大函數(shù):
(1)拷貝構(gòu)造
(2)拷貝賦值
(3)析構(gòu)函數(shù)(清理動(dòng)態(tài)分配的內(nèi)存)
2.析構(gòu)函數(shù)
{
String s1()
String s2(“hello”)
String * p = new String(“hello”)
delete p
}
離開作用域自動(dòng)析構(gòu)抹估,p為什么手動(dòng)析構(gòu)缠黍。
3.Class with pointer members必須有copy ctor和copy op=
使用默認(rèn)拷貝構(gòu)造或拷貝賦值(淺拷貝)
(1)內(nèi)存泄漏
(2)兩個(gè)對(duì)象指向同一塊內(nèi)存(alias)
4.拷貝構(gòu)造函數(shù)
深拷貝,要分配足夠的空間药蜻,把內(nèi)容拷貝進(jìn)去瓷式。編譯器給的默認(rèn)版本只拷貝指針,淺拷貝语泽。
5.拷貝賦值函數(shù)
先把左邊內(nèi)容清空贸典,分配一個(gè)和右邊一樣大的空間,把右邊的內(nèi)容復(fù)制進(jìn)去踱卵。
八瓤漏、堆、棧與內(nèi)存管理
1.stack和heap
Stack 是存在于某作用域的一塊內(nèi)存空間颊埃。當(dāng)調(diào)用函數(shù)蔬充,函數(shù)本身即會(huì)形成一塊stack來(lái)放置它所接收的參數(shù),以及返回地址班利。在函數(shù)本體內(nèi)聲明的任何變量饥漫,其所使用的內(nèi)存塊都取自上述stack。
Heap 是指由操作系統(tǒng)提供的一塊global內(nèi)存空間罗标,程序可動(dòng)態(tài)分配從中獲得若干區(qū)塊庸队。
{
??? Complex c1(1,2);
}
Stack object,其生命在作用域結(jié)束之際結(jié)束积蜻。這種作用域內(nèi)的object,稱為auto object彻消,因?yàn)樗鼤?huì)被自動(dòng)清理竿拆,自動(dòng)調(diào)用析構(gòu)函數(shù)。
{
??? Static Complex c2(1,2);
}
Static object宾尚,其生命在作用域結(jié)束之后仍然存在丙笋,直到整個(gè)程序結(jié)束。
Complex c1(1,2);
int main()
{
}
Global object,其生命在真?zhèn)€程序結(jié)束之后才結(jié)束煌贴。也可以把它視為一種static object御板,其作用域是整個(gè)程序。
Heap object牛郑,其生命在它被delete之際結(jié)束怠肋。如果沒有delete,會(huì)出現(xiàn)內(nèi)存泄漏淹朋。因?yàn)楫?dāng)作用域結(jié)束笙各,p所指的heap object仍然存在,但指針p的生命卻結(jié)束了础芍,作用域之外再也卡不到p酪惭,也就沒有機(jī)會(huì)delete p。
補(bǔ)充:C++內(nèi)存管理
本期專題將從內(nèi)存管理者甲、內(nèi)存泄漏春感、內(nèi)存回收這三個(gè)方面來(lái)探討C++內(nèi)存管理問題。
http://blog.csdn.net/zhanghefu/article/details/5003407
在C++中虏缸,內(nèi)存分成5個(gè)區(qū)鲫懒,他們分別是堆、棧刽辙、自由存儲(chǔ)區(qū)窥岩、全局/靜態(tài)存儲(chǔ)區(qū)和常量存儲(chǔ)區(qū)。
棧宰缤,在執(zhí)行函數(shù)時(shí)颂翼,函數(shù)內(nèi)局部變量的存儲(chǔ)單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放慨灭。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中朦乏,效率很高,但是分配的內(nèi)存容量有限氧骤。
堆呻疹,就是那些由new分配的內(nèi)存塊,他們的釋放編譯器不去管筹陵,由我們的應(yīng)用程序去控制刽锤,一般一個(gè)new就要對(duì)應(yīng)一個(gè)delete镊尺。如果程序員沒有釋放掉,那么在程序結(jié)束后并思,操作系統(tǒng)會(huì)自動(dòng)回收庐氮。
自由存儲(chǔ)區(qū),就是那些由malloc等分配的內(nèi)存塊宋彼,他和堆是十分相似的弄砍,不過它是用free來(lái)結(jié)束自己的生命的。
全局/靜態(tài)存儲(chǔ)區(qū)宙暇,全局變量和靜態(tài)變量被分配到同一塊內(nèi)存中,在以前的C語(yǔ)言中议泵,全局變量又分為初始化的和未初始化的占贫,在C++里面沒有這個(gè)區(qū)分了,他們共同占用同一塊內(nèi)存區(qū)先口。
常量存儲(chǔ)區(qū)型奥,這是一塊比較特殊的存儲(chǔ)區(qū),他們里面存放的是常量碉京,不允許修改厢汹。
2.new
new,先分配memory谐宙,再調(diào)用ctor烫葬。
第3步怎么調(diào)用構(gòu)造函數(shù)?
3.delete
delete:先調(diào)用dtor凡蜻,再釋放memory
4.動(dòng)態(tài)分配所得的內(nèi)存塊搭综,in VC
調(diào)試模式,vc分配的內(nèi)存塊是16的倍數(shù)划栓,52->64
Release mode兑巾,16
上下cookie記錄整塊給的大小,41(應(yīng)該是40忠荞,最后一個(gè)bit表示給出去還是收回來(lái)
5.動(dòng)態(tài)分配所得的數(shù)組
vc用一個(gè)整數(shù)記錄3
array new 一定要搭配array delete
九蒋歌、復(fù)習(xí)String類的實(shí)現(xiàn)
1.構(gòu)造函數(shù)、拷貝構(gòu)造和拷貝賦值不能用const成員函數(shù)委煤,因?yàn)槎家x值堂油,改變了成員數(shù)據(jù)。
2.拷貝賦值返回值碧绞,因?yàn)閺腸習(xí)慣延續(xù)的連續(xù)賦值称诗,所以返回值不能是void,必須是String&头遭。
3.拷貝賦值要判斷是不是自我賦值寓免,if(this=&str) return *this癣诱。
4.引用(&出現(xiàn)在type name后面)和取地址(&出現(xiàn)在object前面)
十、擴(kuò)展補(bǔ)充:類模板袜香、函數(shù)模板和其他
1.static
this pointer
成員函數(shù)只有一份撕予,成員函數(shù)都有一個(gè)隱藏的參數(shù)this pointer,通過this pointer找到它要處理的對(duì)象蜈首。
static data members
static member functions
靜態(tài)成員函數(shù)沒有this pointer实抡,只能處理靜態(tài)數(shù)據(jù)。
注意靜態(tài)成員數(shù)據(jù)的定義(初始化)欢策。
2.把構(gòu)造函數(shù)放在private區(qū)
3.cout
為什么cout能夠接受各種類型的對(duì)象吆寨,操作符<<重載?
4.class template踩寇,類模板
編譯器會(huì)把T全部替換為double啄清,得到一份代碼;把T全部替換為int俺孙,得到一份代碼辣卒。使用模板會(huì)使代碼膨脹(不是缺點(diǎn))。
5.function template睛榄,函數(shù)模板
類模板要明確指出type要綁定為什么荣茫,函數(shù)模板不用明確指出,因?yàn)榫幾g器會(huì)做實(shí)參推導(dǎo)场靴。
C++標(biāo)準(zhǔn)庫(kù)中的算法都是函數(shù)模板啡莉。
6.namespace
標(biāo)準(zhǔn)庫(kù)中所有都包含在std中。
使用標(biāo)準(zhǔn)庫(kù)中的東西:
using directive
using namespace std旨剥;
全部打開
using declaration
using std::cout;
一條一條打開
直接std::cout