国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

C++ 虛基類

2019-11-17 05:27:26
字體:
來源:轉載
供稿:網友

  在《多繼續》中講過的例子中,由類A,類B1和類B2以及類C組成了類繼續的層次結構。在該結構中,類C的對象將包含兩個類A的子對象。由于類A是派生類C兩條繼續路徑上的一個公共基類,那么這個公共基類將在派生類的對象中產生多個基類子對象。假如要想使這個公共基類在派生類中只產生一個基類子對象,則必須將這個基類設定為虛基類。

  虛基類的引入和說明

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

  虛基類說明格式如下:

   virtual <繼續方式><基類名>

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

class A
{
 public:
  void f();
  PRotected:
  int a;
 };
class B : virtual public A
{
  protected:
  int b;
 };
class C : virtual public A
{
  protected:
  int c:
 };
class D : public B, public C
{
  public:
  int g();
  private:
  int d;
};

  由于使用了虛基類,使得類A,類B,類C和類D之間關系用DAG圖示法表示如下:

A{ f(), a }
/ /
B{b} C{c}
/ /
D{g(),d}

從該圖中可見不同繼續路徑的虛基類子對象被合并成為一個對象。這便是虛基類的作用,這樣將消除了合并之前可能出現的二義性。這時,在類D的對象中只存在一個類A的對象。因此,下面的引用都是正確的:

  D n;

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

 void D::g()

 {
  f(); file://對f()引用是正確的。
 }

  下面程序段是正確的。

  D n;
  A *pa;
  pa = &n;

  其中,pa是指向類A對象的指針,n是類D的一個對象,&n是n對象的地址。pa=&n是讓pa指針指向類D的對象,這是正確的,并且也無二義性。
  虛基類的構造函數

  前面講過,為了初始化基類的子對象,派生類的構造函數要調用基類的構造函數。對于虛基類來講,由于派生類的對象中只有一個虛基類子對象。為保證虛基類子對象只被初始化一次,這個虛基類構造函數必須只被調用一次。由于繼續結構的層次可能很深,規定將在建立對象時所指定的類稱為最派生類。C++規定,虛基類子對象是由最派生類的構造函數通過調用虛基類的構造函數進行初始化的。假如一個派生類有一個直接或間接的虛基類,那么派生類的構造函數的成員初始列表中必須列出對虛基類構造函數的調用。假如未被列出,則表示使用該虛基類的缺省構造函數來初始化派生類對象中的虛基類子對象。

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

  C++又規定,在一個成員初始化列表中出現對虛基類和非虛基類構造函數的調用,則虛基類的構造函數先于非虛基類的構造函數的執行。

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

#include
class A
{
public:
A(const char *s) { cout< ~A() {}
};

class B : virtual public A
{
public:
B(const char *s1, const char *s2):A(s1)
{
cout< }
};

class C : virtual public A
{
public:
C(const char *s1, const char *s2):A(s1)
{
cout< }
};

class D : public B, public C
{
public:
D(const char *s1, const char *s2, const char *s3, const char *s4)
:B(s1, s2), C(s1, s3), A(s1)
{
cout< }
};

void main()
{
D *ptr = new D("class A", "class B", "class C", "class D");
delete ptr;
}

  該程序的輸出結果為:

  class A
  class B
  class C
  class D

  在派生類B和C中使用了虛基類,使得建立的D類對象只有一個虛基類子對象。

  在派生類B,C,D的構造函數的成員初始化列表中都包含了對虛基類A的構造函數。

  在建立類D對象時,只有類D的構造函數的成員初始化列表中列出的虛基類構造函數被調用,并且僅調用一次,而類D基類的構造函數的成員初始化列表中列出的虛基類構造函數不被執行。這一點將從該程序的輸出結果可以看出。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 建宁县| 道孚县| 永登县| 平陆县| 正宁县| 登封市| 赫章县| 桓台县| 和田县| 武安市| 盘锦市| 齐河县| 青海省| 聂拉木县| 商河县| 濉溪县| 句容市| 阿拉善盟| 无极县| 定州市| 合川市| 慈溪市| 高邮市| 沂源县| 延川县| 修水县| 延津县| 兰考县| 启东市| 香格里拉县| 洛隆县| 梁河县| 华安县| 宽甸| 云安县| 万载县| 漳州市| 洛阳市| 仙游县| 仙桃市| 桃园县|