簡體   English   中英

由於多個抽象基類,實現兩個具有相同名稱但不同的非協變返回類型的函數

[英]Implement two functions with the same name but different, non-covariant return types due to multiple abstract base classes

如果我有兩個抽象類定義具有相同名稱但不同的非協變返回類型的純虛函數,我如何從這些函數派生並為它們的函數定義實現?

#include <iostream>

class ITestA {
    public:
        virtual ~ITestA() {};
        virtual float test() =0;
};

class ITestB {
    public:
        virtual ~ITestB() {};
        virtual bool test() =0;
};

class C : public ITestA, public ITestB {
    public:
    /* Somehow implement ITestA::test and ITestB::test */
};


int main() {
    ITestA *a = new C();
    std::cout << a->test() << std::endl; // should print a float, like "3.14"
    ITestB *b = dynamic_cast<ITestB *>(a);
    if (b) {
        std::cout << b->test() << std::endl; // should print "1" or "0"
    }
    delete(a);
    return 0;
}

只要我不直接調用C :: test()就沒有任何含糊之處,所以我認為它應該以某種方式工作,我想我還沒找到正確的符號。 或者這是不可能的,如果是這樣:為什么?

好的,這是可能的,而且方式也不是太難看。 我必須添加一個額外的繼承級別:

 ITestA       ITestB     <-- These are the interfaces C has to fulfill, both with test()
    |           |
ITestA_X     ITestB_X    <-- These classes implement the interface by calling a
    |           |             function with a different name, like ITestA_test
    \__________/              which is in turn pure virtual again.
         |
         C               <--  C implements the new interfaces

現在C沒有函數test() ,但是當將C*轉換為ITestA* ,將使用ITestA_testtest()實現。 當將其轉換為ITestB* ,即使是來自ITestA*的dynamic_cast,也將使用ITestB_test的實現。 以下程序打印:3.14 0

#include <iostream>

class ITestA {
    public:
        virtual ~ITestA() {};
        virtual float test() =0;
};

class ITestB {
    public:
        virtual ~ITestB() {};
        virtual bool test() =0;
};

class ITestA_X : public ITestA {
    protected:
        virtual float ITestA_test() =0;
        virtual float test() {
            return ITestA_test();
        }
};

class ITestB_X : public ITestB {
    protected:
        virtual bool ITestB_test() =0;
        virtual bool test() {
            return ITestB_test();
        }
};

class C : public ITestA_X, public ITestB_X {
    private:
        virtual float ITestA_test() {
            return 3.14;
        }
        virtual bool ITestB_test() {
            return false;
        }
};

int main() {
    ITestA *a = new C();
    std::cout << a->test() << std::endl;
    ITestB *b = dynamic_cast<ITestB *>(a);
    if (b) {
        std::cout << b->test() << std::endl;
    }
    delete(a);
    return 0;
}

這有什么可以想到的缺點嗎?

當您聲明ITestA *a = new C() ,您已經創建了一個C對象。 如果調用test與它a->test()它使用C虛擬表找到要執行的代碼。 但是C試圖使用相同簽名test()兩種不同實現,這是不允許的。 您將其聲明為ITestA *事實不會影響方法解析。 您將方法聲明為virtual ,因此無論您用於訪問它的指針類型如何,都可以通過對象的實際類型找到它們。

您不能有兩個具有相同名稱和參數類型的方法。 您需要找到構建此代碼的另一種方法。

我不認為這是可能的。 函數按名稱(和簽名)重載。

暫無
暫無

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

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