簡體   English   中英

覆蓋基類的虛函數,它們不共享公共接口

[英]Override virtual function of base classes, which do not share common interface

#include <iostream>
struct B1
{
    virtual void method()=0;
    virtual ~B1(){}
};

struct B2
{
    virtual void method()=0;
    virtual ~B2(){}
};

struct D: B1, B2
{
    virtual void method()
    {
        std::cout << "D::method\n";
    };
};

int main(int argc,char *argv[])
{
    D d;
    B1 &b1=d;
    B2 &b2=d;
    b1.method();
    b2.method();
    return 0;
}

注意,B1和B2不共享通用接口。

這合法嗎? 如果是 - 在哪個標准? C ++ 98/03/11?

msvc和gcc都編譯好了。

以前我想過,我必須使用一些通用接口來處理這種情況(可能的虛擬繼承)。

這種情況有什么特別的名字嗎?

請問它的工作原理如何? 也許一些ISO參考?

您的代碼格式正確: void D::method()會覆蓋void B1::method()void B2::method()

規范陳述(C ++11§10.3/ 2):

如果虛擬成員函數vf在類BaseDerived類中聲明,直接或間接從Base Derived ,則具有相同名稱的成員函數vf ,parameter-type-list,cv-qualification和ref-qualifier(或如果沒有聲明Base::vf ,那么Derived::vf也是虛擬的(無論是否聲明)並覆蓋Base::vf

B1聲明一個虛擬成員函數void B1::method() D類派生自B1 ,它還聲明了一個具有相同名稱( method ),相同參數列表(無參數),相同cv資格(無資格)和相同ref-qualifier(無資格)的成員函數。

因此, void D::method()會覆蓋void B1::method()

同樣的邏輯適用於void B2::method() (在上面的解釋中只是將B2替換為B1 ),因此void D::method()會覆蓋void B1::method()void B2::method()

afaik這在每個標准中都是合法的。 我不確定它是否有自己的特殊名稱,但它與鑽石問題類似。

如果在D中覆蓋“virtual void method()”,則覆蓋B1和B2中的方法。

編輯:

為什么你沒有“D:B1 :: method和B2 :: method”中的“兩個不同的獨立繼承的虛函數”:

覆蓋方法時,您只能指定函數名稱,返回類型和參數,但是無法在覆蓋時添加有關從哪個繼承的簽名詳細信息。

想象它有可能,那么它看起來像這樣:

struct D: B1, B2
{
    virtual void B1::method()
    {
        std::cout << "D::method\n";
    };
    virtual void B2::method()
    {
        std::cout << "D::method\n";
    };
};

但是看到這個,你已經可以說沒有可能有這樣的東西,因為在打電話時

objectD.method()

你無法指定你打電話給哪一個。 所以,即使有兩種方法都超載,仍然存在區分函數調用的問題。

編輯: “無法指定您正在呼叫哪一個。” 指的是,你不能指定是否要調用B2 :: method的D類重載或B2方法本身。 objectD.B2 ::方法將始終調用B2(不重載)方法(在這種情況下,由於B2沒有實現,因此不會編譯)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM