91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++中的 虛函數 純虛函數 虛基類(virtual)

發布時間:2020-07-30 09:05:24 來源:網絡 閱讀:440 作者:夢T醒 欄目:編程語言

C++中的 虛函數 純虛函數 虛基類(virtual)
前言:需要了解三者的區別,必須要掌握多態的三個必要條件:

  1. 繼承
  2. 重載
  3. 父類指針指向子類對象。

虛函數 純虛函數 虛基類三者區別

1.虛函數是用于多態中virtual修飾父類函數,確保父類指針調用子類對象時,運行子類函數的。
2.純虛函數是用來定義接口的,也就是基類中定義一個純虛函數,基類不用實現,讓子類來實現。
3.虛基類是用來在多繼承中,比如菱形繼承中,如果兩個父類繼承自同一個類,就只實例化一個父類

①虛函數
第一個是沒有使用多態(只用繼承)的一般實現方式:

class A  
{  
public:  
    void printf(){  
        cout<<"printf A"<<endl;  
    }  
};  
class B : public A  
{  
public:  
    void printf(){  
        cout<<"printf B"<<endl;  
    }  
};  
int main(int argc, const char * argv[])  
{  
    A *a = new A();  
    a->printf();  
    B *b = new B();  
    b->printf();  
    return 0;  
}  

結果:

printf A
printf B

這是早期沒有多態的代碼,缺點:代碼冗余
下面是使用了多態但是沒有引用virtual關鍵字的情況:

int main(int argc, const char * argv[])  
{  
    A *a = new B();  
    a->printf();  
    return 0;  
}  

結果:

printf A

因為類的定義都一樣,所以就沒再寫出來了,當父類指針指向子類對象的時候,如果不使用virtual,父類調用方法的時候還是調用了父類自己的方法,沒有調用子類重寫的方法,所以就沒有實現到多態的作用,我們再來在父類中試試加入virtual關鍵字看看:

class A  
{  
public:  
virtual void printf(){  
        cout<<"printf A"<<endl;  
    }  
};  
class B : public A  
{  
public:  
//子類也可以不使用virtual,直接寫為void printf()
    virtual void printf(){  
        cout<<"printf B"<<endl;  
    }  
};  
int main(int argc, const char * argv[])  
{  
    A *a = new B();  
    a->printf();  
    return 0;  
}  

結果

printf B

virtual是加入到父類中的,子類的代碼盡量加上virtual(方便被繼承的子類實現多態),也可以不加,main函數還是父類指針指向子類對象,結果終于可以打印到子類重寫的方法了,所以證實了虛函數是用于多態中virtual修飾父類該重寫的函數,確保父類指針調用子類對象時運行子類函數的。
② 純虛函數
純虛函數就是抽象接口,使用了純虛函數的類不能被實例化,定義了純虛函數的類不用寫純虛函數的實現,由子類實現,下面看代碼:

class A  
{  
public:  
    virtual void printf() =0;  
};  
void A::printf()//純虛函數可以不寫實現  
{  
    cout<<"printf A"<<endl;  
}  
class B : public A  
{  
public:  
    void printf(){  
        cout<<"printf B"<<endl;  
    }  
};  
int main(int argc, const char * argv[])  
{  
    A *a =new A();//編譯出錯,純虛函數的類不能實例化  
    a->printf();  
    return 0;  
}  

virtual void printf() = 0;這是虛函數的寫法,我在下面寫了虛函數的實現 void A::printf(),其實寫不寫都沒關系,寫了也起不了作用,然后我才main函數中嘗試吧純虛函數的類實例化,結果直接報錯,說明純虛函數是不能實例化的。

int main(int argc, const char * argv[])  
{  
    A *a =newB();//這里使用了多態  
    a->printf();  
    return 0;  
}  

結果:

printf B

把main函數的a指向了子類的對象,結果可以正確打印出子類的方法。由此說明了純虛函數也是為多態服務的,它的作用是定義一個接口,讓子類去實現。
③虛基類
虛基類是c++獨有的東西,因為c++中有多繼承,也是關鍵字virtual相關的定義。

先來說說多繼承,如果爺爺類(暫把父類的父類暫定為爺爺類 ),父類繼承自爺爺類。如果孫類繼承自多個父類(聽起來有點怪異),那么如果不使用虛基類,就會實例化多個爺爺類對象(越說越離奇),編譯器會報錯,說有歧義性。如果父類繼承自虛基類,則可以解決多個父類不會實例化多個爺爺的問題,就是只有一個爺爺。

class Grandfather{  
public:  
    int flag;  
    Grandfather(){  
        flag = 1;  
    }  
};  
class Father1:public Grandfather{  
public:  
    Father1(){  
        flag = 2;  
    }  
};  
class Father2:public Grandfather{  
public:  
    Father2(){  
        flag = 3;  
    }  
};  
class Son:public Father1,public Father2{  
};  
int main(int argc, const char * argv[])  
{  
    Son *son = new Son();  
    cout<<son->flag<<endl;//這里編譯錯誤,flag訪問不明確,因為兩個父類中都有flag變量,歧義  
    return 0;  
}  

如果沒有使用虛基類,多個父類繼承自同一個爺爺類,就會產生歧義,為了不產生歧義,代碼可改為(治標不治本):

cout<<son->Father1::flag<<endl;
cout<<son->Father2::flag<<endl;

如果父類繼承虛基類就不同了:

class Grandfather{  
public:  
    int flag;  
    Grandfather(){  
        flag = 1;  
        cout<<"Grandfather flag = "<<flag <<endl;  
    }  
};  
class Father1:virtual public Grandfather{  
public:  
    Father1(){  
        flag = 2;  
        cout<<"Father1 flag = "<<flag<<endl;  
    }  
};  
class Father2:virtual public Grandfather{  
public:  
    Father2(){  
        flag = 3;  
        cout<<"Father2 flag = "<<flag<<endl;  
    }  
};  
class Son:public Father1,public Father2{  
};  
int main(int argc, const char * argv[])  
{  
    Son *son = new Son();  
    cout<<son->flag<<endl;  
    return 0;  
}  

結果:

Grandfather flag = 1

Father1 flag = 2

Father2 flag = 3

3

現在,可以運行了,class Father2:virtual public Grandfather,就是繼承虛基類的寫法,爺爺對象只有一個,爺爺類的變量也只實例化了一次,那為什么最后打印出來的是3呢?看構造函數的順序就可以看出來了,現在構造了爺爺類,再構造第一個繼承的父類,最后繼承第二個繼承的父類,因此flag最后保持在第二個父類的修改值里了。

C++中的 虛函數 純虛函數 虛基類(virtual)總的來說,虛函數 ,純虛函數是為了多態服務,虛基類是為了只實例化一次基類存在的

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

雷波县| 晋中市| 稻城县| 诸暨市| 扶绥县| 堆龙德庆县| 洛川县| 保定市| 娱乐| 金湖县| 女性| 虹口区| 尚义县| 广平县| 拉萨市| 常宁市| 天镇县| 安福县| 台湾省| 惠州市| 平定县| 齐河县| 绥中县| 瑞丽市| 诏安县| 阳江市| 神木县| 宁城县| 苏尼特右旗| 台北县| 永登县| 梧州市| 毕节市| 广宁县| 射洪县| 平江县| 凤庆县| 安宁市| 西林县| 余江县| 会昌县|