6

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

#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() 就没有任何歧义,所以我认为它应该以某种方式工作,我想我只是还没有找到正确的符号。或者这是不可能的,如果是这样:为什么?

4

3 回答 3

3

好吧,有可能,而且方式也不算太难看。我必须添加一个额外的继承级别:

 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 没有 function test(),但是当将 aC*转换为 an时,将使用inITestA*的实现。当将其转换为 时,即使是从 中的 dynamic_cast ,也将使用的实现。以下程序打印:3.14 0test()ITestA_testITestB*ITestA*ITestB_test

#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;
}

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

于 2012-07-07T07:28:22.360 回答
2

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

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

于 2012-07-07T03:15:54.150 回答
0

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

于 2012-07-07T03:16:36.203 回答