數組
數組是數據存放地址的集合,每個地址保存相同類型的數據。
int intArray[10];//int類型爲4個字節,編譯器會分配4*10個字節的連續內存給該數組
數組初始化
int intArray[2]; |
//一維數組聲明 |
int intArray[2] = {1, 2}; |
//對兩個元素都賦值 |
int intArray[2] = {1}; |
//只對第一個元素賦值,第二個默認爲0 |
int intArray[] = {1, 2}; |
//不指定數組大小,根據初始值設定大小 |
XXX xArray[2]; |
//需有不帶參數的默認構造函數,否則xArray數組的元素爲空,即不能創建對象 |
int xArray[2][3]; |
//二維數組聲明 |
int xArray[2][3] = {1,1,...} |
//對2*3個元素進行初始化 |
int xArray[2][3] = {{1,1},...} |
//用大括號對初始值分組 |
數組內存
堆棧內存是有限的,而自由存儲區的內存則大很多,所以在自由存儲區聲明對象
1.XXX xxx[50];//對象數組
2.棧中存儲數組,堆中存儲對象
XXX *xxx[50];//數組存放在堆棧中,數組存放指向對象的指針,指針數組
XXX *x;
for(i<50;..){
x = new XXX;//對象存放在自由存儲區
xxx[i] = x;
}
3.堆中存儲數組和對象
XXX *xxx = new XXX[50];//數組指針,指向對象數組的指針,該對象數組同1定義
銷燬:delete []xxx;///銷燬數組,如果delete xxx;則爲銷燬數組中的第一個對象
字符數組
char cArray[] = "Hello world!";//編譯器自動增加空字符
charcBuff[20];
cin>>cBuff;
cin.get(cBuff,19);
注:cin輸入字符串時,遇到空格或換行則停止向緩衝區寫入,而且當定義的緩衝區大小小於輸入字符數時會溢出寫入。get方法會讀取固定長度的字符到緩衝區,不會造成以上兩種情況。
字符數組複製
charcArray[] = "Hello world!";
charcBuff[20];
strcpy(cBuff,cArray);
strncpy(cBuff,cArray, 19);
strcpy(desStr, srcStr);//字符數組複製,如果長度srcStr>desStr,則會溢出寫入
strncpy(desStr, srcStr, maxLen);//將srcStr空字符\0之前的字符或者前maxLen個字符複製到desStr
鏈表
不良的數組大小定義會造成空間浪費或分配不足等問題
採用鏈表動態分配所需要的存儲空間
每個節點定義指向下一個節點的指針
單一繼承
classB:public A{methodB();}
classC:public A{methodC();}
需要創建對象,既能執行B::methodB,又能執行C::methodC
1.上升:methodB和methodC均提升到A中,但會破壞類的封裝性,增加類A的複雜度
2.下降:RTTI(Runtime Type Identification,運行類型鑑定),eg:爲調用methodC方法下降C類
classB{methodB();}
classC:public B{methodC();}
B objB =new B;
B objC =new C;
C objT1 = dynamic_cast<C*>objB; //爲空
C objT2 = dynamic_cast<C*>objC; //不爲空,正常C類對象,可調用methodC方法
注: 不建議使用此種方式,應採用虛函數、模板或多重繼承來實現。
多重繼承
class C :public A,B
構造函數調用:A,B,C
析構函數調用:C,B,A
class A {void methodComm(); }
class B {void methodComm(); }
或者
class A :D { void methodComm(); }
class B :D { void methodComm(); }
A,B由於繼承自同一個類或者定義了同名方法methodComm時,C中需顯式指出調用的是哪一個類的方法。
objC->A::mehtodComm();
或者,C類覆蓋methodComm方法。
第二種情況,在初始化C類對象時,構造函數調用:D,A,D,B,C,此時,有兩個D類副本
即:A->D ; B->D ; C->A,B
虛繼承
一般類的構造函數只初始化字節的變量和基類,但虛繼承的基類是個例外,該基類由派生性最強的類初始化。
class D{void methodComm(); }
class A :virtual public D
class B :virtual public D
class C :public A, B
注:A, B,C必須在它們的構造函數中初始化D,但當初始化C時,A,B初始化將被忽略。
C對象調用methodComm時,不必再明確methodComm爲哪一個基類的方法
注:不建議使用多重繼承,一是許多編譯器不支持多重繼承,二是增加代碼的複雜度
混合繼承
單一繼承與多重繼承之間的一種折中方式,
classC:public A,B
其中,A爲正常類,B類爲混合繼承類(功能類),該類沒有貨只有很少的數據。
抽象數據類型(虛基類)
含有純虛函數的類爲抽象數據類型(ADT),實例化該類型是非法的。
其他類繼承該類時,必須覆蓋所有純虛函數,否則也爲抽象數據類型。
純虛函數:virtual void method() = 0;
注:一般情況下,ADT作爲接口聲明使用,不對純虛函數進行實現。
規則:對所有子類必須實現的函數設爲純虛函數。