在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++多繼承中重寫不同基類中相同原型的虛函數。
摘自 開心