C++ 如何实现一个模糊的纯虚拟方法

C++ 如何实现一个模糊的纯虚拟方法,c++,C++,我想使用Base::push在我的dervied type派生的中实现一个纯虚拟方法IPusher::push。但是,Derived有自己的push不同签名的方法(是的,我两者都需要) 这无法编译,因为virtualvoidipusher::push(A)在派生中是纯的 对于kicks,我尝试添加覆盖[主要是为了查看错误是否不同] 使用Base::push覆盖 这抱怨说,在覆盖之前就已经被预料到了。你会像这样实施你有问题的想法: class Derived : public Base, publ

我想使用
Base::push
在我的dervied type
派生的
中实现一个纯虚拟方法
IPusher::push
。但是,
Derived
有自己的
push
不同签名的方法(是的,我两者都需要)

这无法编译,因为
virtualvoidipusher::push(A)
派生中是纯的

对于kicks,我尝试添加
覆盖
[主要是为了查看错误是否不同]

使用Base::push覆盖


这抱怨说,
在覆盖之前就已经被预料到了。你会像这样实施你有问题的想法:

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

但是不要。重新思考您的设计或在此处询问一些建议:

基本代码是正确的

除了
A
B
的定义明显缺失之外,您发布的代码是有效的,但是您的
派生的
类仍然是抽象的。汇编如下:

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::push(B)
可能会调用
IPusher::push(A)

或者从
派生的
派生的人可能会尝试访问
IPusher

如果要创建这种类型的对象,就不能离开抽象方法,即使它们不容易访问


提供定义

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


我可以看到我可以使用
Base
实现
IPusher
,但是
Base
非常具体,而
IPusher
在我的真实代码中是另一种对
IPusher
有意义的方法,但对
Base
没有意义,因此,子
派生的
类中的push()不是虚拟的?是否要隐藏基类定义?也许可以实现
IPusher::push
作为
base::push
的包装器?它必须以某种方式实现。为了在实现中继承,您需要使用来自接口的虚拟继承。这与引入过载的问题无关。也许可以试着用两个不同的问题来区分这两个问题。@MichaelDorgan我不想隐藏,这就是为什么我要
使用
it,并将我自己的
push(B)
添加到集合中。从技术上讲,
push(A)
push(B)
IPusher
中都是纯虚拟的,我不知道这个细节是否会增加问题的噪音,因为我理解
Base
不是
IPusher
;因此,
Base
中的
push
方法和
IPusher
/
Derrived
中的
push
方法是两件不同的事情,我们不能简单地称之为
Base::push
方法。还是我错了?@Aldarrion是的,你是对的,也是错的。这是一个糟糕的设计,但您可以从派生的基类成员函数调用完全限定的基类成员函数。我现在明白了,您是对的,因为它很奇怪,很容易出错,除非绝对必要,否则应该避免这种设计。进一步检查后,转发调用是唯一的方法。这是因为Base::push(A)是一个(Base::*)(A)方法,它根本不能转换为(IPusher::*)(A)。我不能让编译器认为它们是。我需要转发给你it@payo设计很可能不需要这种复杂性。也许值得向某人解释设计背后的动机。我相信会出现一个更简单的解决方案。对于我非常奇怪的edge案例,这似乎是一个非常合理的解决方案。正如许多人建议的那样,我应该重新考虑我的更大设计,我会这样做的。但看起来要么是这个解决方案,要么是@RichardHodges,实际上,这是行不通的。这带来了两种不同的方法
push(A)
,就像我最初的工作一样。“干杯和hth.-Alf”的评论实际上是中肯的。如果我想让第一个基类实现来自第二个基类的纯虚拟类型,我需要使用虚拟继承。如果将示例中的
foo
强制转换为
IPusher
,它将调用
IPusherImpl
方法
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;
#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)