class的三大函數(shù)是:
1.拷貝構(gòu)造季惯。
2.拷貝賦值咬最。
3.析構(gòu)翎嫡。
其他備忘:
1. 構(gòu)造函數(shù)函數(shù)分兩類:拷貝構(gòu)造和默認(rèn)構(gòu)造。
2. strlen計(jì)算長(zhǎng)度時(shí)永乌,不包含末尾的 '\0'惑申。
例如如下字符串類String的拷貝構(gòu)造函數(shù):
String::String(const String& str) { m_data = new char[strlen(str.m_data) + 1]; strcpy(m_data,str.m_data); }
此處若不做 strlen(...) + 1,會(huì)造成新的m_data字符串沒(méi)有結(jié)束符的問(wèn)題翅雏。(而且貌似strcpy也會(huì)出錯(cuò)圈驼。)
3. 構(gòu)造函數(shù)放在private里面時(shí),對(duì)象將不能直接構(gòu)造望几。
4. 對(duì)于有指針成員的類绩脆,注意要自己實(shí)現(xiàn)三大函數(shù)。使用默認(rèn)生成的函數(shù)會(huì)造成不良后果:
(1)使用默認(rèn)的拷貝構(gòu)造和拷貝賦值橄抹,會(huì)造成新生成的對(duì)象內(nèi)部指針指向來(lái)源對(duì)象的動(dòng)態(tài)分配空間靴迫,造成動(dòng)態(tài)分配空間的共享。這會(huì)造成不可預(yù)計(jì)的嚴(yán)重錯(cuò)誤楼誓。(比如1玉锌,其中一個(gè)對(duì)象更改了“動(dòng)態(tài)空間”,另一個(gè)對(duì)象的所謂的“動(dòng)態(tài)空間”也被一起改動(dòng)了疟羹。比如2主守,其中的一個(gè)對(duì)象銷毀了空間釋放了,此時(shí)一個(gè)對(duì)象的“動(dòng)態(tài)空間”阁猜,可能又會(huì)分配給其他對(duì)象丸逸,讀出的數(shù)據(jù)可能被其他對(duì)象更改,或者自己寫入數(shù)據(jù)又更改了其他對(duì)象的數(shù)據(jù)剃袍。等等)
(2)使用默認(rèn)的析構(gòu)函數(shù)黄刚,則會(huì)造成動(dòng)態(tài)生成的空間沒(méi)有被釋放,造成內(nèi)存泄漏的問(wèn)題民效。
5. 拷貝復(fù)制函數(shù)注意添加入口判斷憔维。
例如字符串類String的拷貝復(fù)制函數(shù):
String& String::operator= (const String& str) { if(this == &str) { return *this; } delete[] m_data; m_data = new char[strlen(str.m_data) + 1]; strcpy(m_data,str.m_data); return *this; }
此處若不做錯(cuò)誤處理,會(huì)因?yàn)楹竺娴膁elelte[] m_data;操作而把自己的數(shù)據(jù)刪除畏邢,造成數(shù)據(jù)丟失业扒,以及后面strlen、strcpy執(zhí)行出錯(cuò)的問(wèn)題舒萎。
6. 拷貝復(fù)制函數(shù)編寫時(shí)要考慮 s3 = s2 = s1這種連續(xù)拷貝復(fù)制的情況程储。
例如字符串類String的拷貝復(fù)制函數(shù):
String& String::operator= (const String& str) { ...... return *this; }
此處要在代碼末尾添加return *this
,返回類型寫成自己類的引用。
7. 堆空間和椪吕穑空間的比較:
(1)堆空間比椞穑空間大很多,因此如果要?jiǎng)?chuàng)建很大的臨時(shí)空間败徊,使用堆空間比較不容易達(dá)到空間上限帚呼。
(2)棧空間創(chuàng)建和銷毀由程序自己完成皱蹦。堆空間創(chuàng)建和銷毀要由代碼明確創(chuàng)建和銷毀煤杀,不然會(huì)造成內(nèi)存泄漏問(wèn)題。
(3)如果創(chuàng)建的數(shù)組變量大小不確定沪哺,那么使用堆空間來(lái)動(dòng)態(tài)創(chuàng)建會(huì)比較不浪費(fèi)空間沈自。