21天學通C++--閱讀筆記3

數組

數組是數據存放地址的集合,每個地址保存相同類型的數據。

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.上升:methodBmethodC均提升到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 BC必須在它們的構造函數中初始化D,但當初始化C時,AB初始化將被忽略。

C對象調用methodComm時,不必再明確methodComm爲哪一個基類的方法

 

注:不建議使用多重繼承,一是許多編譯器不支持多重繼承,二是增加代碼的複雜度

 

混合繼承

單一繼承與多重繼承之間的一種折中方式,

classC:public A,B

其中,A爲正常類,B類爲混合繼承類(功能類),該類沒有貨只有很少的數據。

 

抽象數據類型(虛基類)

含有純虛函數的類爲抽象數據類型(ADT),實例化該類型是非法的。

其他類繼承該類時,必須覆蓋所有純虛函數,否則也爲抽象數據類型。

純虛函數:virtual void method() = 0;

 

注:一般情況下,ADT作爲接口聲明使用,不對純虛函數進行實現。

規則:對所有子類必須實現的函數設爲純虛函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章