虛基類 虛函式 純虛函式和抽象類

2021-06-29 05:03:07 字數 2762 閱讀 4065

一:虛基類   

在《多繼承》中講過的例子中,由類a,類b1和類b2以及類c組成了類繼承的層次結構。在該結構中,類c的物件將包含兩個類a的子物件。由於類a是派生類c兩條繼承路徑上的乙個公共基類,那麼這個公共基類將在派生類的物件中產生多個基類子物件。如果要想使這個公共基類在派生類中只產生乙個基類子物件,則必須將這個基類設定為虛基類。   

虛基類的引入和說明   

前面簡單地介紹了要引進虛基類的原因。實際上,引進虛基類的真正目的是為了解決二義性問題。   

虛基類說明格式如下:   

virtual   《繼承方式》《基類名》   

其中,virtual是虛類的關鍵字。虛基類的說明是用在定義派生類時,寫在派生類名的後面。例如:   

class   a   

;   

class   b   :   virtual   public   a   

;   

class   c   :   virtual   public   a   

;   

class   d   :   public   b,   public   c   

;   

由於使用了虛基類,使得類a,類b,類c和類d之間關係用dag圖示法表示如下:   

a   

/           /   

b     c   

/           /   

d   

從該圖中可見不同繼承路徑的虛基類子物件被合併成為乙個物件。這便是虛基類的作用,這樣將消除了合併之前可能出現的二義性。這時,在類d的物件中只存在乙個類a的物件。因此,下面的引用都是正確的:   

d   n;   

n.f();   //對f()引用是正確的。   

void   d::g()   

下面程式段是正確的。   

d   n;   

a   *pa;   

pa   =   &n;   

其中,pa是指向類a物件的指標,n是類d的乙個物件,&n是n物件的位址。pa=&n是讓pa指標指向類d的物件,這是正確的,並且也無二義性。   

虛基類的建構函式   

前面講過,為了初始化基類的子物件,派生類的建構函式要呼叫基類的建構函式。對於虛基類來講,由於派生類的物件中只有乙個虛基類子物件。為保證虛基類子物件只被初始化一次,這個虛基類建構函式必須只被呼叫一次。由於繼承結構的層次可能很深,規定將在建立物件時所指定的類稱為最派生類。c++規定,虛基類子物件是由最派生類的建構函式通過呼叫虛基類的建構函式進行初始化的。如果乙個派生類有乙個直接或間接的虛基類,那麼派生類的建構函式的成員初始列表中必須列出對虛基類建構函式的呼叫。如果未被列出,則表示使用該虛基類的預設建構函式來初始化派生類物件中的虛基類子物件。   

從虛基類直接或間接繼承的派生類中的建構函式的成員初始化列表中都要列出這個虛基類建構函式   的呼叫。但是,只有用於建立物件的那個最派生類的構造函式呼叫虛基類的建構函式,而該派生類的基類中所列出的對這個虛基類的構造函式呼叫在執行中被忽略,這樣便保證了對虛基類的物件只初始化一次。   

c++又規定,在乙個成員初始化列表中出現對虛基類和非虛基類建構函式的呼叫,則虛基類的建構函式先於非虛基類的建構函式的執行。   

下面舉一例子說明具有虛基類的派生類的建構函式的用法。   

#include  

class   a   

;   

在許多情況下,在基類中不能對虛函式給出有意義有實現,而把它說明為純虛函式,它的實現留給該基類的派生類去做。這就是純虛函式的作用。下面給出乙個純虛函式的例子。   

#include  

class   point   

virtual   void   set()   =   0;   

virtual   void   draw()   =   0;   

protected:   

int   x0,   y0;   

};   

class   line   :   public   point   

void   set()     

void   draw()     

protected:   

int   x1,   y1;   

};   

class   ellipse   :   public   point   

void   set()     

void   draw()     

protected:   

int   x2,   y2;   

};   

void   drawobj(point   *p)   

void   setobj(point   *p)   

void   main()   

{   

line   *lineobj   =   new   line;   

ellipse   *elliobj   =   new   ellipse;   

drawobj(lineobj);   

drawobj(elliobj);   

cout《抽象類是為了抽象和設計的目的建立的,建立抽象類是為了通過它多型的使用其中的成員函式。抽象類處於類層次的上層,抽象類無法例項化。

1)  純虛函式:是乙個在基類中宣告的虛函式,在基類中沒有定義具體的操作內容。

virtual 函式型別 函式名(參數列)=0;

2)帶有純虛函式的類為抽象類,抽象類不能例項化,但我們可以宣告乙個抽象類的指標和引用,通過指標和引用,我們就看就可以訪問派生類物件,這種訪問具有多型性特徵。

虛基類 純虛函式 抽象類

虛基類 純虛函式和抽象類 1 虛基類 在 多繼承 中講過的例子中,由類a,類b1和類b2以及類c組成了類繼承的層次結構。在該結構中,類c的物件將包含兩個類a的子物件。由於類a是派生類c兩條繼承路徑上的乙個公共基類,那麼這個公共基類將在派生類的物件中產生多個基類子物件。如果要想使這個公共基類在派生類中...

虛基類,抽象類,虛函式,純虛函式,virtual

虛基類 在說明其作用前先看一段 class a class b public a class b virtual public a 大家以為這段 的輸出結果是什麼?有的人可能會馬上回答funprint of class a 與 funprint of class b 因為第一次輸出是引用類a的實 例...

虛函式 虛基類 抽象類

一 虛基類 解決二義性,防止雙份拷貝間接基類。否則得用作用域分辨符來區分進行的多個拷貝 將共同基類設定為虛函式,這是從不同的路徑繼承過來的同名資料成員在記憶體中就只有乙個拷貝,同乙個函式名也只有乙個對映。虛基類的宣告是在派生類的定義過程中進行的,語法形式為 class 派生類名 virtual繼承方...