C 技術點積累 4 繼承 多型 抽象類

2021-07-05 07:16:50 字數 4490 閱讀 4209

1)對於單個類來說,訪問修飾符:

public 修飾的成員變數 方法 在類的內部 類的外部都能使用;

protected: 修飾的成員變數方法,在類的內部使用 ,在繼承的子類中可用 ;其他 類的外部不能被使用;

private: 修飾的成員變數方法 只能在類的內部使用 不能在類的外部;

2)c++中的繼承方式會影響子類的對外訪問屬性:

public繼承:父類成員在子類中保持原有訪問級別

private繼承:父類成員在子類中變為private成員

protected繼承:父類中public成員會變成protected

父類中protected成員仍然為protected

父類中private成員仍然為private

private成員在子類中依然存在,但是卻無法訪問到。不論種方式繼承基類,派生類都不能直接使用基類的私有成員 。

3)c++中的繼承方式(public、private、protected)會影響子類的對外訪問屬性,判斷某一句話,能否被訪問:

a)看呼叫語句,這句話寫在子類的內部、外部

b)看子類如何從父類繼承(public、private、protected)

c)看父類中的訪問級別(public、private、protected)

4)派生類訪問控制的結論:

a. protected 關鍵字 修飾的成員變數 和成員函式 ,是為了在家族中使用 ,是為了繼承;

b. 專案開發中 一般情況下 是 public;

5)型別相容性原則:

a)子類物件可以當作父類物件使用——父類指標 (引用) 指向 子類物件

b)子類物件可以直接賦值給父類物件——指標(引用)做函式引數,實參是子類指標(例項),形參卻要求的是父類指標(例項)

c)子類物件可以直接初始化父類物件——可以用子類物件直接   初始化   父類物件,子類就是一種特殊的父類

d)父類指標可以直接指向子類物件

e)父類引用可以直接引用子類物件

在替代之後,派生類物件就可以作為基類的物件使用,但是只能使用從基類繼承的成員。型別相容規則是多型性的重要基礎之一。

6)繼承中的構造析構呼叫原則:

在子類物件構造時,需要  呼叫父類建構函式  對其  繼承得來的成員  進行初始化;

在子類物件析構時,需要  呼叫父類析構函式  對其  繼承得來的成員  進行清理;

子類物件在建立時會首先呼叫父類的建構函式,父類建構函式執行結束後,執行子類的建構函式,當父類的建構函式有引數時,需要在子類的初始化列表中顯示呼叫;

析構函式呼叫的先後順序與建構函式相反;

7)繼承與組合混搭情況下,構造和析構呼叫原則: 

(類的組合其實就是「包含」,a類裡面有乙個資料成員的b類)

原則:先構造父類(父之父),再構造成員變數(組合類的物件),最後構造自己

先析構自己,                   再析構成員變數(組合類的物件),最後析構父類

(父之父)

繼承與組合混搭情況例子:

#include using namespace std;

class object //祖宗類

virtual ~a() //虛析構函式

private:

char *p;

};class b : public a

~b()

private:

char *p;

};class c : public b

~c()

private:

char *p;

};//不使用虛析構函式

//下面的程式不會表現成 多型 這種屬性,只執行了 父類的 析構函式

//想通過 父類指標 把 所有的子類物件的析構函式 都執行一遍

//想通過 父類指標 釋放所有的子類資源

//使用 虛析構函式 來實現

void howtodelete(a *base)

void main()

4)區別過載、重寫(虛函式)和重定義

#include using namespace std;

//重寫(虛函式) 過載 重定義

//重寫發生在2個類之間

//過載必須在乙個類之間

//重寫分為2類

//1 虛函式重寫 將發生多型

//2 非虛函式重寫 (重定義)

class parent

virtual void func()

virtual void func(int i)

virtual void func(int i, int j)

virtual void func(int i, int j, int m, int n) };

class child : public parent

/* void abc(int a)

*/virtual void func(int i, int j)

virtual void func(int i, int j, int k) };

//過載、重寫(虛函式)和重定義

void main()

5)多型的實現原理當類中宣告虛函式時,編譯器會在類中生成乙個虛函式表,虛函式表是乙個儲存類成員函式指標的資料結構,虛函式表是由編譯器自動生成與維護的,virtual成員函式會被編譯器放入虛函式表中,當存在虛函式時,每個物件中都有乙個指向虛函式表的指標(c++編譯器給父類物件、子類物件提前布局vptr指標;當進行howtoprint(parent *base)函式是,c++編譯器不需要區分子類物件或者父類物件,只需要在base指標中,找vptr指標即可。),vptr一般作為類物件的第乙個成員 ,存在虛函式時,每個物件中都有乙個指向虛函式表的指標(vptr指標)。

說明1:通過虛函式表指標vptr呼叫重寫函式是在程式執行時進行的,因此需要通過定址操作才能確定真正應該呼叫的函式。而普通成員函式是在編譯時就確定了呼叫的函式。在效率上,虛函式的效率要低很多。

說明2:出於效率考慮,沒有必要將所有成員函式都宣告為虛函式。

加上virtual關鍵字 c++編譯器會增加乙個指向虛函式表的指標 。物件在建立的時侯,由編譯器對vptr指標進行初始化 ;只有當物件的構造完全結束後vptr的指向才最終確定;父類物件的vptr指向父類虛函式表;子類物件的vptr指向子類虛函式表。

6)父類指標和子類指標的步長

結論:父類p++與子類p++步長不同;不要混搭,不要用父類指標++方式運算元組。

class parent

virtual void print()

private:

int a;

};class child : public parent

virtual void print()

private:

int b;

};void main()

; pp = array;

pc = array;

pp->print();

pc->print(); //多型發生

pp++;

pc++;

pp->print();

pc->print(); //多型發生

pp++;

pc++;

pp->print();

pc->print(); //多型發生

程式自動宕機,從上圖可以看出在基類指標++以後,指向記憶體的出錯!

C 技術 多型 抽象類

2.實現過程是 用基類的指標類指向派生類的位址,在呼叫虛函式 因為呼叫虛函式是通 過查虛表執行函式的,但虛表中的虛函式指標可以在繼承的時候被子類覆蓋 3.在多型中會出現父類指標指向子類,那麼父類指標用完後會 delete,那麼這時候缺省會調 用父類的虛構函式,如果子類中有記憶體要釋放,那就被洩露掉了...

繼承 多型 抽象類 介面

繼承 這個世界到處是繼承的例子比如動物是乙個最基礎的物件,人 豬 貓貓 狗狗都從動物繼承了基本的屬性和方法。繼承就是乙個層次結構,先抽象出乙個基本的東西,然後具體的物件從這個基本的東西來繼承,繼承後再寫他特有的,這樣就可以做到復用了。隱藏 如果基類和繼承類裡有一樣的方法,在子類裡呼叫的時候會怎麼樣,...

C 學習 多型 抽象類

多型 概念 run time binding 函式名和函式入口點的繫結發生在程式執行時刻 complie time binding 程式再編譯時進行函式名和函式入口的繫結 多型的本質 run time binding 多型的條件 1.必須有繼承 2.子類要把虛函式重寫 override 派生類的vi...