C++虛繼承解說(shuō)-創(chuàng)新互聯(lián)

1.概括

專注于為中小企業(yè)提供網(wǎng)站建設(shè)、成都網(wǎng)站制作服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)漣水免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

    在CPlusPlus多繼承編程中時(shí)常遇到這樣一個(gè)問(wèn)題--若子類實(shí)現(xiàn)多個(gè)基類或接口繼承,多基類或接口中存在成員名相同,在客戶與實(shí)現(xiàn)類之間的通信時(shí)編譯器報(bào)錯(cuò)“不能這樣使用,會(huì)產(chǎn)生二義性”由于這個(gè)問(wèn)題的解決方法很多。比如說(shuō),可以把相同的成員名給改過(guò)來(lái)。但是,從專業(yè)的角度,可能虛擬繼承會(huì)解決這個(gè)問(wèn)題。那接下來(lái)我看看c++是怎么避免這種問(wèn)題的。

2.概念

    當(dāng)在多條繼承路徑上有一個(gè)公共的基類,在這些路徑中的某幾條匯合處,這個(gè)公共的基類就會(huì)產(chǎn)生多個(gè)實(shí)例(或多個(gè)副本),若只想保存這個(gè)基類的一個(gè)實(shí)例,可以將這個(gè)公共基類說(shuō)明為虛基類。      class 派生類名:virtual 繼承方式  基類名

    virtual是關(guān)鍵字,聲明該基類為派生類的虛基類。

    例如:

    class 派生類: virtual 基類1,virtual 基類2,...,virtual 基類n
    
    {
        
        ...//派生類成員聲明
    
    };

    在多繼承情況下,虛基類關(guān)鍵字的作用范圍和繼承方式關(guān)鍵字相同,只對(duì)緊跟其后的基類起作用。 聲明了虛基類之后,虛基類在進(jìn)一步派生過(guò)程中始終和派生類一起,維護(hù)同一個(gè)基類子對(duì)象的拷貝。C++使用虛擬繼承(Virtual Inheritance),解決從不同途徑繼承來(lái)的同名的數(shù)據(jù)成員在內(nèi)存中有不同的拷貝造成數(shù)據(jù)不一致問(wèn)題,將共同基類設(shè)置為虛基類。這時(shí)從不同的路徑繼承過(guò)來(lái)的同名數(shù)據(jù)成員在內(nèi)存中就只有一個(gè)拷貝,同一個(gè)函數(shù)名也只有一個(gè)映射。這樣帶來(lái)的有點(diǎn)是解決了二義性問(wèn)題,也節(jié)省了內(nèi)存,避免了數(shù)據(jù)不一致的問(wèn)題。

3.用例

二義性:

#include <iostream>
using namespace std;
 //Base 
class Base
{
 public:
 Base(){cout << "Base called..."<< endl;}
 void print(){cout << "Base print..." <<endl;}
  private:
 };
 
 //Sub 
class Sub //定義一個(gè)類 Sub 
{
public:
 Sub(){cout << "Sub called..." << endl;}
  void print(){cout << "Sub print..." << endl;}
private:
};

  //Child 
class Child : public Base , public Sub //定義一個(gè)類Child 分別繼承自 Base ,Sub 
{
  public:
  Child(){cout << "Child called..." << endl;}
 private:
 };
 
int main(int argc, char* argv[])
{
 Child c;
  //不能這樣使用,會(huì)產(chǎn)生二意性,VC下error C2385 
  //c.print();  
 
 //只能這樣使用 
  c.Base::print();
  c.Sub::print();
  system("pause");
  return 0;
  }

多重繼承:

//說(shuō)明:C++虛擬繼承學(xué)習(xí)演示  
//環(huán)境:VS2005  
//blog:pppboy.blog.163.com  
//----------------------------------------------------  
#include "stdafx.h"  
#include <iostream>
using namespace std;  
int gFlag = 0;  
class Base  
{
public:  
 Base(){cout << "Base called : " << gFlag++ << endl;}  
 void print(){cout << "Base print" <<endl;}  
};

class Mid1 : public Base  
{
 public:  
 Mid1(){cout << "Mid1 called" << endl;}  
 private:  
};

class Mid2 : public Base  
{
public:  
 Mid2(){cout << "Mid2 called" << endl;}  
};

class Child:public Mid1, public Mid2  
{
public:  
 Child(){cout << "Child called" << endl;}  
};

int main(int argc, char* argv[])  
{
Child d;
//不能這樣使用,會(huì)產(chǎn)生二意性  
     //d.print();  
//只能這樣使用  
d.Mid1::print();
d.Mid2::print();
system("pause");  
return 0;  
}

output:

Base called : 0
 Mid1 called
 Base called : 1
 Mid2 called
 Child called
 Base print
 Base print

虛擬繼承:

#include "stdafx.h"  
#include <iostream>
using namespace std;  
int gFlag = 0;  
class Base  
{
public:  
Base(){cout << "Base called : " << gFlag++ << endl;}  
void print(){cout << "Base print" <<endl;}  
};

class Mid1 : virtual public Base  
{
public:  
Mid1(){cout << "Mid1 called" << endl;}  
private:  
};

class Mid2 : virtual public Base  
{
public:  
Mid2(){cout << "Mid2 called" << endl;}  
};

class Child:public Mid1, public Mid2  
{
public:  
Child(){cout << "Child called" << endl;}  
};

int main(int argc, char* argv[])  
{
Child d;
//這里可以這樣使用  
d.print();
//也可以這樣使用  
d.Mid1::print();
d.Mid2::print();
system("pause");  
return 0;  
}

4.總結(jié)

    在多繼承情況下,虛基類關(guān)鍵字的作用范圍和繼承方式關(guān)鍵字相同,只對(duì)緊跟其后的基類起作用。聲明了虛基類之后,虛基類在進(jìn)一步派生過(guò)程中始終和派生類一起,維護(hù)同一個(gè)基類子對(duì)象的拷貝。觀察類構(gòu)造函數(shù)的構(gòu)造順序,拷貝也只有一份。

5.擴(kuò)展

    windows編程的程序員們?cè)谶M(jìn)行COM編程的時(shí)候會(huì)遇到這樣的一個(gè)問(wèn)題------繼承接口IUnknown這一塊使用非虛擬繼承。這是為什么呢?如果有這樣的疑問(wèn)是很正常。之所以這樣是由于會(huì)導(dǎo)致與COM不兼容的vtbl。比如:

    struct IX : public IUnknown

    {

        //....

    };

    struct IY : public IUnknow

    {

        //....

    };

 客戶程序?qū)崿F(xiàn):

...
if(iid == IID_IUnknown) {
        //the client wants the IUnknown interface.
        *ppv = static_cast<IX*>(this);
    } else if(iid == IID_IX){
        //the client wants the IX interface.
     *ppv = static_cast<IX*>(this);
    } else if(iid == IID_IY) {
        *ppv = static_cast<IY*>(this);
    }
    ...

    可見,程序中他們是通過(guò)類型轉(zhuǎn)換的。不然,IX和IY的vtbl中的頭三個(gè)函數(shù)指向的將不是IUnknown的三個(gè)成員函數(shù)。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

網(wǎng)站題目:C++虛繼承解說(shuō)-創(chuàng)新互聯(lián)
轉(zhuǎn)載來(lái)于:http://bm7419.com/article12/dihsdc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁(yè)設(shè)計(jì)公司手機(jī)網(wǎng)站建設(shè)、搜索引擎優(yōu)化、電子商務(wù)、品牌網(wǎng)站制作網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)