程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++多繼承中重寫不同基類中相同原型的虛函數

C++多繼承中重寫不同基類中相同原型的虛函數

編輯:C++入門知識

在C++多繼承體系當中,在派生類中可以重寫不同基類中的虛函數。下面就是一個例子:


[cpp]
class CBaseA 

public: 
    virtual void TestA(); 
}; 
class CBaseB 

public: 
    virtual void TestB(); 
}; 
class CDerived : public CBaseA, public CBaseB 

public: 
    virtual void TestA(); // 重寫基類CBaseA中的虛函數TestA() 
    virtual void TestB(); // 重寫基類CBaseB中的虛函數TestB() 
}; 
void Test() 

    CDerived D; 
    CBaseA *pA = &D; 
    CBaseB *pB = &D; 
    pA->TestA(); // 調用類CDerived的TestA()函數 
    pB->TestB(); // 調用類CDerived的TestB()函數 

可是,如果兩個基類中有一個相同原型的虛函數,例如下面這樣:

[cpp]
class CBaseA 

public: 
    virtual void Test(); 
}; 
class CBaseB 

public: 
    virtual void Test(); 
}; 
怎樣在派生類中重寫這兩個相同原型的虛函數呢? 也許這種情況並不常見,可是這種情況卻確實存在。比如說開發的時候使用的兩個類庫是不同的廠商提供的,或者說這兩個類庫是由公司的不同開發小組開發的。對前者來說,修改基類的接口是不可能的;對後者來說,修改接口的代價很大。 如果在派生類中直接重寫這個虛函數,那麼2個基類的Test()虛函數都將被覆蓋。這樣的話就只能有一個Test()的實現,而不是像前面的例子那樣有不同的實現。


[cpp]
class CDerived : public CBaseA, public CBaseB 

public: 
    virtual void Test(); 
}; 
void Test() 

    CDerived D; 
    CBaseA *pA = &D; 
    CBaseB *pB = &D; 
    // 下面2行代碼都將調用類CDerived的Test()函數 
    pA->Test(); 
    pB->Test();  

為了實現第一個例子中的那樣,在派生類CDerived中重寫不同基類中相同原型的虛函數Test(),可以使用下面的方法。 首先,不需要對2個基類進行任何修改(在實際的開發當中,修改基類的可能性非常小)。

[cpp]
class CBaseA 

public: 
    virtual void Test(); 
}; 
class CBaseB 

public: 
    virtual void Test(); 
}; 
現在,為這個繼承體系添加2個中間類,分別從2個基類派生。

[cpp]
class CMiddleBaseA : public CBaseA 

private: 
    // 真正的實現函數 
    // 設置為純虛函數,在派生類裡必須實現 
    virtual void CBaseA_Test() = 0; 
    // 改寫繼承下來的虛函數 
    // 僅僅直接調用真正的實現函數 
    virtual void Test()  
    {  
        CBaseA_Test();  
    } 
}; 
// 與類CMiddleBaseA采用相同的方法 
class CMiddleBaseB : public CBaseB 

private: 
    virtual void CBaseB_Test() = 0; 
    virtual void Test()  
    {  
        CBaseB_Test();  
    } 
}; 

然後,類CDerived以上面2個中間類作為基類來派生。分別重寫上面2個基類中原型不同的純虛函數,添加不同的實現代碼。

[cpp]
class CDerived : public CMiddleBaseA, public CMiddleBaseB 

private: 
    // 重寫從中間類繼承下來的虛函數 
    virtual void CBaseA_Test(); // 這裡實際上是重寫CBaseA的Test() 
    virtual void CBaseB_Test(); // 這裡實際上是重寫CBaseB的Test() 
}; 
void Test() 

    CDerived D; 
    CBaseA *pA = &D; 
    CBaseB *pB = &D; 
    // 調用類CBaseA的Test()函數 
    // 由於C++多態的特性,實際上調用的是類CDervied中的CBaseA_Test()函數 
    pA->Test();  
    // 調用類CBaseB的Test()函數  www.2cto.com
    // 由於C++多態的特性,實際上調用的是類CDervied中的CBaseB_Test()函數 
    pB->Test(); 

現在以上面代碼中的pA->Test();這行代碼來說明上面的方案是怎麼實現的。 首先,由於虛函數Test()在類CBaseA的派生類CMiddleBaseA中被重寫,所以這行代碼會去調用類CMiddleBaseA的Test()函數; 然後,類CMiddleBaseA的Test()函數會去調用實現函數CBaseA_Test(); 最後,由於虛函數CBaseA_Test()在類CMiddleBaseA的派生類CDerived中被重寫,所以真正調用的是類CDerived中的CBaseA_Test()函數。 同樣的道理,代碼pB->Test();實際上調用的是類CDervied中的CBaseB_Test()函數。 通過上面的方法就可以在C++多繼承中重寫不同基類中相同原型的虛函數。

摘自 開心

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved