子類所繼承的兩個父類有同名純虛函數,怎麼辦?
子類所繼承的兩個父類有同名純虛函數,怎麼辦?
返回值,參數類型全都一樣.怎麼辦? 謝謝!例如:
struct Base1
{
virtual void fun()=0;
};struct Base2
{
virtual void fun()=0;
};struct child : Base1 , Base2
{
virtual void fun() override {}
//這到底是實現了Base1::fun還是Base2::fun?
//我想兩個分別實現怎麼辦?
};
這裡有好幾種情況:
首先,child裡面什麼都不寫,但是又要去調用child中的fun。
其次,child寫了,那就一切正常。
再次,如果child中你不實現,但是使用了作用域限定表達式,或者讓虛函數在Base1上起作用,那也沒有問題。
你要辦什麼。想override就override好了咯。又沒影響。
總覺得這種情況應該去改兩個父類……
不能直接改兩個父類的源碼的話,那你可以建兩個virtual wrapper class分別繼承兩個父類,然後把這個相同的函數隱藏起來……然後再繼承兩個wrapper
不過說到底多繼承就是邪道啊!!//這到底是實現了Base1::fun還是Base2::fun?
這是覆蓋掉了,跟父類的實現沒關係了
//我想兩個分別實現怎麼辦?
完全相同的簽名,做不到啊
估計題主擔心的是這樣會不會衝突或者可不可以這樣用。這樣做是可以的,子類的func()覆蓋掉了兩個父類的同名虛函數,「子類關於父類的兩個虛表對應func()的位置上存儲的都是子類func()的成員方法地址」,這只是籠統的說法,不同的編譯器具體的細節可能不同。題主可以從itanium c++ ABI或者gcc的技術文檔中查到相關資料。
另外,誰讓C++有多繼承這種鬼呢!
如果你在Child子類重寫fun(),效果是相當於同時重寫了Base1::fun()和Base2::fun()。本來C++的標準里是要添加一個特性來避免這種情況的,但是設計者們認為這種情形很罕見,不值得為此添加額外的特性。而且從類設計的角度來看,如果兩個介面有一樣的方法,那麼他們的行為也應該是一樣的。
如果要避免,那麼應該這樣:
struct Base1
{
virtual void fun1()=0;
};
struct Base2
{
virtual void fun2()=0;
};
struct child : Base1 , Base2
{
virtual void fun1() override {} // 重寫Base1::fun1()
virtual void fun2() override {} // 重寫Base2::fun2()
};
順便說下,在VC++中,我發現還可以這樣做:
struct Base1
{
virtual void fun()=0;
};
struct Base2
{
virtual void fun()=0;
};
struct child : Base1 , Base2
{
virtual void Base1::fun() override {} // 重寫Base1::fun()
virtual void Base2::fun() override {} // 重寫Base2::fun()
};
注意Base1::fun()和Base2::fun()必須是純虛函數。
尚不清楚這個是VC++的擴展還是新的標準。兩個都要實現可以這樣,不過只能放在類內。
class Child
: public Base1
, public Base2
{
public:
void Base1::func() override
{
}
void Base2::func() override
{
}
};
應該是兩個父類虛函數都會覆蓋吧
推薦閱讀:
※為什麼GCC5.x.x版本中的std::string不再採用寫時複製的實現,而改用了SSO的實現?
※如何用 C/C++ 求 1 到 1000 內的所有完全數?
※reinterpret_cast把const string*轉換成const char*出錯?
※為什麼用了using namespace std會報錯?
※c++如何在編譯期判斷一個對象是否是字元串字面值?