C++多继承中重写不同基类中相同原型的虚函数
生活随笔
收集整理的這篇文章主要介紹了
C++多继承中重写不同基类中相同原型的虚函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在C++多繼承體系當中,在派生類中可以重寫不同基類中的虛函數。下面就是一個例子:
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()函數?}可是,如果兩個基類中有一個相同原型的虛函數,例如下面這樣:
class CBaseA?{?public:?virtual void Test();?};?
class CBaseB?{?public:?virtual void Test();?};怎樣在派生類中重寫這兩個相同原型的虛函數呢?也許這種情況并不常見,可是這種情況卻確實存在。比如說開發的時候使用的兩個類庫是不同的廠商提供的,或者說這兩個類庫是由公司的不同開發小組開發的。對前者來說,修改基類的接口是不可能的;對后者來說,修改接口的代價很大。如果在派生類中直接重寫這個虛函數,那么2個基類的Test()虛函數都將被覆蓋。這樣的話就只能有一個Test()的實現,而不是像前面的例子那樣有不同的實現。
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個基類進行任何修改(在實際的開發當中,修改基類的可能性非常小)。
class CBaseA?{?public:?virtual void Test();?};?
class CBaseB?{?public:?virtual void Test();?};現在,為這個繼承體系添加2個中間類,分別從2個基類派生。
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個基類中原型不同的純虛函數,添加不同的實現代碼。
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()函數?// 由于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++多繼承中重寫不同基類中相同原型的虛函數。
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()函數?}可是,如果兩個基類中有一個相同原型的虛函數,例如下面這樣:
class CBaseA?{?public:?virtual void Test();?};?
class CBaseB?{?public:?virtual void Test();?};怎樣在派生類中重寫這兩個相同原型的虛函數呢?也許這種情況并不常見,可是這種情況卻確實存在。比如說開發的時候使用的兩個類庫是不同的廠商提供的,或者說這兩個類庫是由公司的不同開發小組開發的。對前者來說,修改基類的接口是不可能的;對后者來說,修改接口的代價很大。如果在派生類中直接重寫這個虛函數,那么2個基類的Test()虛函數都將被覆蓋。這樣的話就只能有一個Test()的實現,而不是像前面的例子那樣有不同的實現。
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個基類進行任何修改(在實際的開發當中,修改基類的可能性非常小)。
class CBaseA?{?public:?virtual void Test();?};?
class CBaseB?{?public:?virtual void Test();?};現在,為這個繼承體系添加2個中間類,分別從2個基類派生。
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個基類中原型不同的純虛函數,添加不同的實現代碼。
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()函數?// 由于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++多繼承中重寫不同基類中相同原型的虛函數。
總結
以上是生活随笔為你收集整理的C++多继承中重写不同基类中相同原型的虚函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JEECG开源团队招募新成员 2014年
- 下一篇: CSS公用文件