C++ 由于有多个抽象基类,实现两个名称相同但返回类型不同的非协变函数

C++ 由于有多个抽象基类,实现两个名称相同但返回类型不同的非协变函数,c++,multiple-inheritance,virtual-functions,overriding,abstract-base-class,C++,Multiple Inheritance,Virtual Functions,Overriding,Abstract Base Class,如果有两个抽象类定义了一个具有相同名称但不同的非协变返回类型的纯虚函数,如何从中派生并为它们的两个函数定义一个实现 #include <iostream> class ITestA { public: virtual ~ITestA() {}; virtual float test() =0; }; class ITestB { public: virtual ~ITestB() {}; virtua

如果有两个抽象类定义了一个具有相同名称但不同的非协变返回类型的纯虚函数,如何从中派生并为它们的两个函数定义一个实现

#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;
}
#包括
伊泰斯塔级{
公众:
虚拟~ITestA(){};
虚拟浮点测试()=0;
};
ITETB类{
公众:
虚拟~ITestB(){};
虚拟布尔测试()=0;
};
C类:公共ITestA、公共ITestB{
公众:
/*以某种方式实现ITestA::test和ITestB::test*/
};
int main(){
ITestA*a=新的C();

std::cout test()当您声明
ITestA*a=new C()
时,您已经创建了一个
C
对象。如果您使用
a->test()对其调用
test
,它必须使用
C
虚拟表来查找要执行的代码。但是
C
正在尝试对同一签名使用两种不同的实现
test()
,这是不允许的。您将其声明为
ITestA*
的事实并不影响方法解析。您将方法声明为
virtual
,因此可以通过对象的实际类型找到它们,而不管您用于访问它的指针的类型如何


您不能有两个名称和参数类型相同的方法。您需要找到另一种方法来构造此代码。

我认为这是不可能的。函数按名称(和签名)重载。

好的,这是可能的,而且这种方法也不太难看。我必须添加额外的继承级别:

 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

这有什么你能想到的缺点吗?

如果我在基类中实现这两个函数,而不是使它们纯粹(但保持它们虚拟!),那么一切都会很顺利,因此方法解析对编译器来说似乎不是什么大问题。
类ITestA{public:virtual~ITestA(){};虚拟浮点测试(){return 3.14;}};类ITestB{public:virtual~ITestB(){};虚拟bool测试(){return false;}}};类C:public ITestA,public ITestB{}那是因为你提供了一个基类列表,它决定了你的
test
方法中哪一个获胜。你的
C
类只有一个
test
方法。C应该有一个
C.ITestA::test
和一个
C.ITestB::test
。当使用
ITestA*a=C
时,它会自动使用
C.ITestA::test
。所以我需要的是一种直接定义
c.ItestA::test
的方法,而不是依赖继承将其带到c(与
ITestB::test
相同)。这是不可能的?或者它使用
c.ItestA::test
已经不是标准的,只是编译器选择的“运气”(gcc 4.4)不,代码> >代码>不应该有两个代码>测试< /Calp>函数。实际上,它不能有两个。C++中的函数用它们的名称和参数类型来区分。两个函数具有相同的名称和相同的参数类型。它们不能共存。您必须想一个不同的方法来做您想要的。正确,<代码> C<代码>代码>t有两个函数,但每个
C
实例都有,比如
C
(很抱歉,在示例中没有选择更好的名称),由一个
ITestA
实例和
ITestB
实例组成,这两个实例都有一个
test
函数。我从有关菱形继承问题的阅读中了解到了很多。这实际上为我带来了一个解决方案!我会将其作为新答案发布。不过,感谢您的帮助,否则我不会找到它。可能重复e of
#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;
}