三大函數(shù):拷貝構造,拷貝賦值,析構
1.如string s3(s1); //s1是已有的一個對象,這是拷貝構造函數(shù)(可以理解為同類對象互為友元)
2.s3=s1是拷貝賦值,跟上面的拷貝構造函數(shù)一樣,把每個成員數(shù)據(jù)復制到s3里
3.帶指針的類要自己寫拷貝構造函數(shù):可能面臨的問題:編譯器只是把指針指向同一個地址,一旦原指針被釋放,這個拷貝來的指針將懸空。
4.指針賦值為0相當于NULL
5.拷貝構造的函數(shù)聲明:string(const char* cstr = 0);拷貝賦值的聲明:string&
operator=(const string& str);帶指針的類要寫這兩個~string()為析構函數(shù)。以上三個特殊函數(shù)為big three函數(shù)。
6.有動態(tài)分配的類(有指針的類多半要動態(tài)分配),析構函數(shù)清理動態(tài)分配的空間
7.拷貝構造里要穿件足夠的空間放新的內容。
8.拷貝賦值:要首先檢測自我賦值:如:if(this==&str)return *this(因為接下來的操作可能有先釋放自己的操作,不檢測自我賦值會把對象誤釋放)
9.接上一條:拷貝賦值可以先釋放自己,再創(chuàng)建一個足夠大的空間,接下來同拷貝構造。
堆、棧與內存管理
1.Complex c1(1,2);//這表示c1占用的空間來自stack。這個stack是作用域內的空間。例如函數(shù)調用時會創(chuàng)建一個stack,用來存放接收的參數(shù)和返回地址。調用結束自己釋放。
2.Complex* p=new Complex(3);//p指向的內容存放在heap(或者稱system
heap)里,使用結束要手動釋放。否則會造成內存泄漏(memory leak)。因為指針p會被清理,但它指向的內容不會被清理。
3.1中的c1又稱auto object,auto表示會被自動清理
4.Static對象的生命在作用域(scope)之后仍然存在,直至整個程序結束。
5.Cpp的new時先分配memory再調用構造函數(shù)。如:complex *pc = new complex(1,2);編譯器把new轉化為:void* mem = operator new(sizef(complex)); pc =
static_cast(mem);//轉型pc->complex::complex(1,2);new的內部調用的是malloc(n)
6.delete編譯器化為先調析構函數(shù),再釋放指針內存
7.分配出的內存狀態(tài):頭尾有cookies,4個字節(jié),中間有系統(tǒng)給的32+4個字節(jié)的空間,如果是數(shù)組,還有4字節(jié)的空間儲存數(shù)組元素個數(shù)。
8.Array new要array delete。即delete后加[]
擴展補充:類模板,函數(shù)模板,及其他
1.Static成員數(shù)據(jù)和成員函數(shù)有單獨的儲存空間,static函數(shù)沒有this指針,多個對象的數(shù)據(jù)有不同空間儲存,成員函數(shù)只儲存一次。Static函數(shù)只處理static數(shù)據(jù)。
2.一般成員函數(shù)通過this指針知道哪個對象調用此函數(shù)。
3.定義static成員數(shù)據(jù):在類外寫形如double Account::my_rate = 8.0;的語句。
4.調用static函數(shù)的方法:①通過object調用:例如Account::set_rate(5.0);即類名::函數(shù)名(參數(shù)表)(沒有定義對象之前要調用static函數(shù)可以這樣調用)②通過class name調用,跟調用一般的成員函數(shù)一樣。
5.Singleton:一個類的私有成員數(shù)據(jù)里有本類的static對象,比如A類的對象a。外界想得到這個a的地址,可以在public里寫一個static函數(shù),外界通過此函數(shù)得到這個對象的地址,進而做別的操作。(這樣也要把構造函數(shù)放在private里)
6.上一條更好的寫法:Meyers Singleton:把定義static對象的語句寫在那個static函數(shù)里。有人調用才會定義那個對象,并且由于這個對象是static的,函數(shù)調用結束后也不會被釋放。
7.類模板,template。定義對象時,編譯器把T全替換。(模板會造成代碼膨脹,但這是必要的)
8.函數(shù)模板:template函數(shù)模板不用把這個T寫出來,因為編譯器會做參數(shù)推導,推導出來T是什么。
9.Cpp標準庫里的算法都是寫的函數(shù)模板
10.Namespace: namespace名稱。一個命名空間。using namespace std用std這個命名空間。(using directive)如果不使用這個命名空間,調用里面的內容要這么寫std::cin<<…;(using declaration)或:using std::cout這樣寫之后不用每條都加std::(不想全部展開,只用里面的一部分)
11.Operator type()const;這樣的函數(shù)可以實現(xiàn)向type類型的強制轉換。
感悟:聽課自我感覺問題不大,但是寫起作業(yè)來就會報奇奇怪怪的錯。例如我碰到的在析構函數(shù)里寫delete leftUp; 原本以為很簡單的一句釋放內存,卻會讓程序崩潰。紙上得來終覺淺,絕知此事要躬行。所以多寫,多做才會成長。