如何实现模棱两可的纯虚方法

时间:2018-07-23 21:09:28

标签: c++

我想使用Base::push来实现我的派生类型IPusher::push的纯虚方法Derived。但是,Derived拥有自己的具有不同签名的push方法(是的,我需要两者)。

class Base
{
public:
  void push(A);
};

class IPusher
{
public:
  virtual void push(A) = 0;
}:

class Derived : public Base, public IPusher
{
public:
  using Base::push;
  void push(B);
};

无法编译,抱怨virtual void IPusher::push(A)内的Derived是纯粹的

对于踢球,我尝试添加override [主要是为了查看错误是否不同]

using Base::push override;

这抱怨说;应该早于override

2 个答案:

答案 0 :(得分:3)

您将像这样实现您可疑的想法:

class Derived : public Base, public IPusher
{
public:
    void push(A a) override
    {
        // implement in terms of Base::push(A)
        Base::push(a); 
    }

    void push(B);
};

但是不要。在这里重新考虑您的设计或提出建议:https://softwareengineering.stackexchange.com/questions/tagged/c%2b%2b

答案 1 :(得分:2)

基本代码正确

您发布的代码除了AB的明显缺失的定义是有效的之外,但您的Derived类仍然是抽象的。编译如下:

class A{};
class B{};

class Base
{
public:
  void push(A);
};

class IPusher
{
public:
  virtual void push(A) = 0;
};

class Derived : public Base, public IPusher
{
public:
  using Base::push;
  void push(B);
};

int main() {
  return 0;
}

派生仍然是抽象的-为什么?

但是,当您尝试创建类型为Derived的对象时-例如,在主行中添加Derived foo;行-您会收到错误消息:

error: cannot declare variable ‘foo’ to be of abstract type ‘Derived’
   Derived foo;
           ^
note:   because the following virtual functions are pure within ‘Derived’:
 class Derived : public Base, public IPusher
       ^
note:      virtual void IPusher::push(A)
   virtual void push(A) = 0;

是的,您不希望在使用IPusher::push时直接访问Derived,但是也许可以在其他现有方法的内部间接访问它吗?例如,您的Derived::push(B)可能会呼叫IPusher::push(A)

或者也许某个来自Derived的人会尝试访问IPusher

如果您要创建该类型的对象,即使它们不容易访问,您只是不能离开抽象方法。


提供定义

例如,您想为IPusher::push(A)提供实现,但想从界面中隐藏它?另外,您不希望它干扰来自Base的定义。 我看到的避免定义冲突的唯一解决方案是创建一个中间类IPusherImpl,该中间类将提供该定义,然后在Derived中从中继承。 这是一个完整的运行示例(将使用c ++ 11编译):

#include <iostream>

class A{};
class B{};

class Base
{
public:
  void push(A) { std::cout << "Base::push(A)\n"; }
};

class IPusher
{
public:
  virtual void push(A) = 0;
};

class IPusherImpl : public IPusher
{
  public:
  void push(A) override { std::cout << "IPusher::push(A) overriden in IPusherImpl\n"; }
};

class Derived : public Base, public IPusherImpl
{
public:
  using Base::push;
  void push(B) { std::cout << "Derived::push(B)\n"; }
};

int main() {
  Derived foo;
  A a;
  B b;
  foo.push(a);
  foo.push(b);
  return 0;
}

输出:

Base::push(A)
Derived::push(B)