繼承模式分為單繼承和多繼承
在多繼承中會有相應的一些問題產生,比如資料冗餘,二義性等問題,那麼我們要如何解決這種問題。利用虛繼承便可以解決,在虛繼承的時候由虛基表可以去除資料冗餘和二義性。
那麼函式可不可以寫成是虛函式呢?寫成虛函式有什麼作用?
在派生類裡重寫基類的虛函式可以實現多型。
#include
using
namespace
std;
class a
private:
int _a;
};class b:public a
virtual
void print1()
private:
int _b;
};
以上**中函式print()就構成了多型,因為在基類a中先定義了這個函式,後面在派生類b中先繼承了a類,然後再重寫了基類a中的虛函式print(),那麼這兩個虛函式就構成了多型。由此我們可以看出構成多型的條件有:首先必須是虛函式,其次它的函式名,返回型別,以及函式引數都必須是相同的,以及兩個虛函式不能在同乙個作用域中(應該分別在基類和派生類中)。
在虛函式中存在乙個叫虛表(也叫虛函式表)的東西
虛函式表裡存的是虛函式,虛表的結束位置由0標識。
虛函式在類裡只佔乙個指標的大小,然後這個被標識的指標指向的是虛函式的位址。由上圖我們也可以看出來,每個虛函式也都有自己的指標,指向的是這個虛函式的位址,也就是說無論這個虛函式裡面寫了多少**,實際上在這個類裡都只佔乙個指標的大小。而這個虛函式裡存的都在指標指向的那個位址裡。
由圖可以看出類b中因為繼承了類a,所以它的裡面也會有虛表,由記憶體的圖可以看出,a的虛表的位址是在b的虛表的上面,也就是說在繼承a類後,會先將a類的虛函式建立,再建立b類自己的虛函式。
虛函式要注意的幾點有:建構函式不能定義為虛函式,析構函式和建構函式最好不要呼叫虛函式,基類的析構函式最好能定義為虛函式,因為在派生類中呼叫析構函式時會呼叫基類的析構函式釋放基類定義的成員。
純虛函式
在成員函式的形參後面加上0,就叫做純虛函式。
ps:友元關係是不能繼承的。
多繼承:
多繼承裡,子類自己的虛函式(虛表)是往第乙個繼承的父類虛表裡放。
子類如果重寫了多個父類的虛函式,那麼每個父類的虛函式都會重寫。
多繼承的情況下(虛表)指標會發生偏移。
此處推薦一篇對多型和虛函式描述的極好文章!
虛函式多型
一 知識點 1 乙個操作隨著所傳遞的物件型別的不同能夠做出不同的反應,其行為模式成為多型。p413 2 基類與派生類的同名操作,只要標記上virtual,則該操作便具有多型性。p416 3 一旦標記基類的函式為虛函式,便有連鎖反應,後面繼承的類中一切同名成員函式都變成了虛函式。如果是引發實際複製動作...
虛函式多型
虛函式訪問知識點 王道程式設計師求職寶典 p163 1 與普通函式一樣,虛函式可通過物件名來呼叫,此時編譯器採用靜態聯編。通過物件名訪問虛函式時,呼叫哪個類的函式取決於定義物件名的型別。物件是基類就調基類,物件是子類就調相應的子類。2 使用指標訪問非虛函式時,編譯器會根據指標本身的型別決定呼叫哪個函...
多型,虛函式,純虛函式
多型 借助虛函式,基類指標既可以使用基類 父類 的成員函式,也可以使用派生類 子類 的成員函式,它有多種形態,或多種表現方式,這就是多型 簡單說就是同一條語句可以執行不同的操作,看起來有不同表現方式,這就是多型。多型存在的三個條件 注意 派生類 子類 中的虛函式必須覆蓋 不是過載 基類 父類 中的虛...