C 之菱形繼承與虛繼承 含虛函式

2021-08-19 17:51:37 字數 3654 閱讀 7845

物件導向的三大特徵:

封裝,多型,繼承

前面我們已經講了繼承的一些知識點,在這基礎上,我們講的時候再涉獵一些多型的只是。

下面我們先接著上次講有虛函式的菱形虛繼承

首先什麼是虛函式。?

虛函式:在類裡面,函式前面有virtual關鍵字的成員函式就是虛函式。

**塊:

class base

~base()

virtual void dis()//加了關鍵字virtual,dis就成了虛函式

int pub;

protected:

int pro;

private:

int pri;

};

我們先講幾個知識點:

1.虛函式(virtual function)是通過一張虛函式表(virtual table)來實現的。簡稱為v-table。

2.在乙個類中,

成員函式有虛函式的話,那麼,這個物件的前四個位元組一定是存放乙個指向這個虛函式表(簡稱虛表)    的指標。

虛表裡面放的是虛函式的位址

3.對於菱形繼承這樣,有

多個基類的類物件,則會有多個虛表,每乙個基類對應乙個虛表,同時,虛表的順序和繼承時的順序相同。

4.即使是存在虛基類指標,

虛表指標也是在虛基類指標的上方,這是為了保證正確取到虛函式的偏移量。

舉個簡單的例子

**塊:

#define _crt_secure_no_warnings 1

#include#includeusing namespace std;

class base

~base()

virtual void dis()//加了關鍵字virtual,dis就成了虛函式

~a()

virtual void dis()//記住這個dis(),每個類都有這個虛函式

int a;//把a放在公有位置,便於類外訪問

};class b :virtual public a//加上了關鍵字virtual,變成了虛繼承

~b()

virtual void dis()//記住這個dis(),每個類都有這個虛函式

private:

int b;

};class c :virtual public a//加上了關鍵字virtual,變成了虛繼承

~c()

virtual void dis()//記住這個dis(),每個類都有這個虛函式

private:

int c;

};class d :public b, public c//分別公有繼承b,c

~d()

virtual void dis()//記住這個dis(),每個類都有這個虛函式

private:

int d;

};void test()

int main()

分析:它有乙個虛基類a,所以存在虛基表指標;

它每個類還有虛函式,所以存在,虛表指標;

虛表指標位於虛基表指標上方(這個第二種情況解釋) ;

但是這裡比較特殊的就是每個類中的虛函式都是一樣的,所以就構成了這種特殊的物件模型。

在這裡我們通過呼叫監視和檢視記憶體來觀察:

截圖:

通過上圖我們知道,要是

每個類都有一樣的虛函式,則虛表指標就不會存在與每乙個物件中,而是只在虛基類的前四個位元組,然後這個指標就指向了存放著統一的虛函式的虛表。

2.這種情況就是每個類的虛函式存在著不同。

**塊:

#define _crt_secure_no_warnings 1

#include#includeusing namespace std;

typedef void(*func) ();//函式指標

class a

~a()

virtual void dis()//記住這個dis(),每個類都有這個虛函式

int a;//把a放在公有位置,便於類外訪問

};class b :virtual public a//加上了關鍵字virtual,變成了虛繼承

~b()

virtual void dis()//記住這個dis(),每個類都有這個虛函式

virtual void func()//和d類相同的虛函式func()

virtual void func2()//b類自己的虛函式

int b;

};class c :virtual public a//加上了關鍵字virtual,變成了虛繼承

~c()

virtual void dis()//記住這個dis(),每個類都有這個虛函式

virtual void func3()//c類自己的虛函式

int c;

};class d :public b, public c//分別公有繼承b,c

~d()

virtual void dis()//記住這個dis(),每個類都有這個虛函式

virtual void func()//和b類相同的虛函式func()

virtual void func4()//d類自己的虛函式

int d;

};void printvtable(int* vtable)

cout << endl;

}int main()

執行結果加後期截圖1:

截圖2:

模型草圖:

分析:

先了解一下多型:

概念:多型就是多種形態,c++的

多型分為靜態多型和動態多型

1. 靜態多型:主要通過函式的過載和模板來實現,是在編譯時決定,也叫編譯時多型。

2. 動態多型:就是通過繼承重寫基類的虛函式實現的多型,是在執行時決定,也叫執行時多型。

很多東西在截圖上面都畫出來了,所以我也不知道該怎麼再分析了

相信大家通過自己動手去實現一遍,會有更加深刻的了解。。

C 菱形繼承與虛繼承

12 29 study.cpp 定義控制台應用程式的入口點。include stdafx.h include using namespace std 菱形繼承 多繼承 兩個類共同繼承於同乙個類 class animal class sheep1 public animal class tuo1 pu...

菱形繼承和菱形虛繼承

繼承是c 的一大特點,我們通過菱形繼承和菱形虛繼承對繼承進行進一步的分析。菱形繼承 建立乙個基類a讓b1和b2公有繼承於它,讓c公有繼承b1和b2。class a a int a class b1 public a b1 int b1 class b2 public a b2 int b2 clas...

C 多繼承 菱形繼承 虛繼承

b和c都單繼承了a d繼承了b和c 是多繼承 有兩個或兩個以上的基類就是多繼承 class a public int ma class b public a public int mb class c public a public int mc class d public b,public c ...