天天看點

抽象類和虛基類的定義及用途

抽象類不能執行個體化對象!

為了讓一個類成為抽象類,至少必須有一個純虛函數。包含至少一個純虛函數的類視為抽象類!

classA
{
public:
virtual void lock(void)=0;
virtual void unlock(void)=0;
virtual ~A(void);
}
//将函數lock()和unlock()初始化為0使它們成為純虛函數,沒有0這個初使化器,它們僅僅是虛函數。
           

如果子類是一個非抽象類的的話,必須重寫父抽象類的所有抽象方法,如果子類是一個抽象類的話,可以重寫父抽象類的抽象方法,也可以繼承父抽象類的抽象方法~

虛基類

class x1:virtual public x    //virtual也可以寫在public後面
{
//……
};
           

虛基類可以解決二義性的問題

其實說白了就是解決多重多級繼承造成的二義性問題。例如有基類B,從B派生出C和D,然後類F又同時繼承了C和D,現在類F的一個對象裡面包含了兩個基類B的對象,如果F通路自己的從基類B那裡繼承過來的的資料成員或者函數成員那麼編譯器就不知道你指的到底是從C那裡繼承過來的B對象呢還是從D那裡繼承過來的B對象。

于是虛基類誕生了,将C和D的繼承方式改為虛繼承,那麼F通路自己從B那裡繼承過來的成員就不會有二義性問題了,也就是将F對象裡的B對象統一為一個,隻有一個基類B對象,下面是一段代碼說明了對虛基類的使用。

#include <iostream>
using namespace std;
class A
{
    public:
    int i;
    void showa(){cout<<"i="<<i<<endl;}
};
class B:virtual public A      //此處采用虛繼承
{
    public:
    int j;
};
class C:virtual public A      //此處采用虛繼承
{
    public:
    int k;
};


class D:public B,public C//調用析構函數時先調用虛基類的構造函數,然後挨個最後調用基類的析構函數,構造函數反過來
{
    public:
    int m;
};
int main()
{
    A a;
    B b;
    C c;
    a.i=1;
    a.showa();
    b.i=2;
    b.showa();
    c.i=3;
    c.showa();
    D d;
    d.i=4;
    d.showa();
    //cout << "Hello world!" << endl;
    return 0;
}

           

從這個代碼我們可以看出B,C,D從A那裡繼承過來了i這個變量并且它們之間不會有任何影響,如果B和C不是虛繼承方式的,那麼d.i=4;就不能編譯通過了。

建立派生類的對象時:先調用基類構造函數,對象成員構造函數(單選上的,并不太懂),派生類本身構造函數.

繼續閱讀