七:拷貝構造、拷貝復制、析構
1.編譯器自動給的BIG THREE,其中默認拷貝構造函數(shù)、拷貝賦值函數(shù)(參數(shù)是本類的對象或引用),會忠實地對每一個bit進行拷貝,因此如果類中有指針的時候,必須自己實現(xiàn)可以深拷貝的拷貝構造、拷貝賦值;
拷貝構造函數(shù)的兩種調用方式:
?String s2(s1);//以s1為藍本,調用拷貝構造函數(shù),創(chuàng)建s2
?String s2=s1;//創(chuàng)建新的s2,內部如果有指針成員,則指針成員需要調用其構造函數(shù)完成深拷貝
2.深拷貝:把指針指向的內容拷貝過去;淺拷貝:只拷貝了指針,兩個指針指向相同的內容,會導致內存泄露;
3.拷貝賦值函數(shù)中,先把自己的指針指向的內容清空,再重新創(chuàng)建一塊和拷貝源側一樣大的內存,最后把拷貝源側的內容拷貝到這塊內存上;一定要進行自我賦值檢測:否則,如果進行自我賦值,先清空內容,無法再繼續(xù)賦值;
拷貝賦值的步驟:
?自我賦值檢測
?清空自身內存塊 ??
?分配與源側一樣大的內存 ? ? ?????
?memoryCopy ? ???????
4、拷貝構造函數(shù)、賦值操作符編寫的時 候,兩個要點
1、對于父類部分,首先考慮要調用父類的拷貝構造函數(shù)、賦值操作符進行初始化
2、對于指針成員,考慮其深度拷貝問題:在構造函數(shù)中,在賦值操作符中,不完全一樣
八:堆、棧與內存管理
1.Stack:是存在于某作用域內的一塊內存空間,調用函數(shù),會形成一個stack,其中局部變量的生命周期僅限于該作用域。
2.Heap:操作系統(tǒng)提供的一塊global內存空間,可以動態(tài)分配,生命在delete后結束
3.Static:靜態(tài)對象,生命周期是整個程序的執(zhí)行期
4.Global:全局對象,生命周期也是整個程序的執(zhí)行期,可以看做static
5.New:用于在heap中動態(tài)分配空間,編譯器分解為三個動作:
Complex* pc=new Complex(1,2)
?Void* mem=operator new(sizeof(Complex));//operator new調用malloc分配內存
?Pc=static_cast(mem);//void*指針轉型
?Pc->Complex::Complex(1,2);//調用構造函數(shù)
6.Delete:釋放new分配的動態(tài)內存空間,編譯器分解為兩個動作:清內存,放指針
String* ps=new string(“hello”);
Delete ps;
?String::~strting(ps);//調用析構函數(shù),會把動態(tài)分配的內存清零,指針還存在
?Operator delete(ps);//釋放內存,調用free(ps),刪除string中的指針
7.VC中動態(tài)分配內存塊
Debug模式:28+4*2(所用內存上下的0xfd)+4*2(全部內存首尾的cookie)
Release模式:4*2(只會多兩個cookie)
分配的內存塊必須是16字節(jié)的整數(shù)倍
Cookie的末位為1表示該內存被分配,為0表示內存未被分配,倒數(shù)第二位*16為內存字節(jié)數(shù)

8.動態(tài)分配數(shù)組內存
多開辟一個字節(jié)用以保存數(shù)組大小,以在delete[]的時候,多次喚起dtor

9.Array new一定要搭配array delete
如果數(shù)組中的對象不帶pointer,則使用delete pointer和delete[] pointer都一樣,并不會造成內存泄露,如果數(shù)組中的對象攜帶pointer,則使用delete pointer會泄露內存。
EX:string *s=new string[10];
Delete s;
?String::~string()//只數(shù)組第一個成員調用析構函數(shù),在該析構函數(shù)中會清空內存,釋放*c_string指針。但是其余9個數(shù)組成員的析構函數(shù)沒有被調用,在堆上分配的內存沒有被回收
?Free(s);//釋放s指針,s指針指向的內存被成功回收
十、類模板、函數(shù)模板
1.Static:
?static data存儲在靜態(tài)數(shù)據(jù)區(qū),只有一份,所有對象共享。
?Static member func沒有this指針,所以不能處理普通數(shù)據(jù)成員,只能處理靜態(tài)數(shù)據(jù)成員??梢酝ㄟ^對象、類名調用。
2.This:成員函數(shù)在內存空間中只有一份,不同的對象在調用成員函數(shù)的時候,成員函數(shù)怎么找到對象的數(shù)據(jù)成員呢?::成員函數(shù)有一個隱藏參數(shù):this指針,編譯在第一個位置,成員函數(shù)通過this指針找到對象的數(shù)據(jù)成員。
3.類模板使用時傳入類型參數(shù),編譯期具現(xiàn)化為模板類,模板類運行時生成對象。
4.類模板在使用時需明確指出參數(shù),函數(shù)模板在使用時,編譯期可以進行參數(shù)推導,參數(shù)推導時,類型參數(shù)需要隱式支持函數(shù)內對該參數(shù)的要求。
Q:1、m_data =newchar[strlen(c) + 1];//new typename[length]