如何使用两个具有相同名称但返回类型不同的纯虚方法

时间:2018-05-30 16:05:57

标签: c++ overloading multiple-inheritance pure-virtual

我有一个公开的接口A和一个后端实现类C,如下所示:

struct A
{
    virtual void f() = 0;
};

struct C : public A
{
    virtual void f() override
    {
    }
};

我想逐步迁移到新界面BB将使用相同的方法,但返回类型可能不同。我希望我的实现类实现AB,以便遗留代码可以继续使用A,直到迁移,但新代码可以用B编写。我知道如果我有两个具有完全相同签名的纯虚方法,我在实现类中只需要一个覆盖。但如果他们的回报类型不同,我就不知道怎么做......

struct A
{
    virtual void f() = 0;
};

struct B
{
    virtual int f() = 0;
};


struct C : public A, public B
{
    // How do I implement both versions of f() here??
};

3 个答案:

答案 0 :(得分:0)

这至少与VS2017编译:

struct A
{
    virtual void f() = 0;
};

struct A2: public A
{
    void f() { Af(); }
    virtual void Af() = 0;
};

struct B
{
    virtual int f() = 0;
};

struct B2 : public B
{
    int f() { return Bf(); }
    virtual int Bf() = 0;
};

struct C : public A2, public B2
{
    void Af() {}
    int Bf() { return 42; }
};

编辑:无法在Paul Accisano自己的回答中添加评论,所以我把它放在这里。

略微修改保罗的答案。通过使未使用的默认参数成为受保护的类,您仍然可以进行正确的类型检查,并避免与另一个成员函数发生类型冲突。

struct A
{
    virtual void f() = 0;
};

struct B
{
protected:
    class disambiguator {};
public:
    virtual int f(disambiguator ignoreMe = disambiguator()) = 0;
};


struct C : public A, public B
{
    virtual void f() override {}
    virtual int f(disambiguator ignoreMe) override { return 42; }
};

A *createA() { return new C; }
B *createB() { return new C; }

这方面的一个应用可能是从原始指针到智能指针的逐步迁移。

答案 1 :(得分:0)

我这样做的方式是

struct A {}
struct B {}
struct OldImpl : public A {}
struct NewImpl : public B {}
struct Combined : public AImpl, public BImpl {}

然后你可以将组合传递给想要A或B的任何东西。 这个问题是你的OldImpl和NewImpl完全是分开的。他们不允许彼此互动;这意味着您无法在A中调用setFoo()并在B中的getFoo()中获得相同的值。这可能与您所描述的不同。

要解决此问题,请不要创建第二个界面。它无论如何都不会起作用,因为现在xxx()可能无效,而后来的int,你可能想要对返回值做一些事情。如果你真的想在婴儿步骤中做,请创建一个分支,更改单个函数返回值,测试它,合并它,重复。

答案 2 :(得分:0)

感谢您的好评!但我确实找到了自己的解决方案:好的旧可选参数!

struct A
{
    virtual void f() = 0;
};

struct B
{
    virtual int f(int ignoreMe = 0) = 0;
};


struct C : public A, public B
{
    virtual void f() override {}
    virtual int f(int) override {}
};

使用AB的外部用户没有歧义,也不需要更改任何参数。内部没有歧义,因为参数在实现类中是非可选的。迁移完成后,可以删除可选参数以及A