未实现的纯虚方法问题

时间:2014-01-18 12:19:29

标签: c++ design-patterns inheritance

我有以下界面A:

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

我还有从A:

派生的接口B,C
class B : public A
{
    ...
}

class C : public A
{
    ...
}

类X实现B和Y实现C.它们都来自D类

class X : public D, public B {...}
class Y : public D, public C {...}

这两个类都具有相同的A :: f()实现,所以我将此实现移动到D.现在当我尝试实例化X或Y时,我得到一个错误,即没有为它们实现f()。

虽然在基类中实现了相同的方法,但编译器并不认为它是纯虚函数的实现。我该怎么办?

5 个答案:

答案 0 :(得分:1)

D::f()的实施对A::f()一无所知。您必须从D(以及ABCD派生f(),或在X中实施Y }和D。实现可能非常简单 - 只需调用D::f()中的函数(但不要将其称为{{1}},以避免歧义)。

修改 :(添加信息)

但是,如果你可以自由地在类之间移动这个函数,我很不确定它甚至必须是方法,而不是一些辅助函数。

答案 1 :(得分:0)

如果类D不是从类A派生的,那么函数D::f()不能用于解决实现纯虚拟A::f()的需要。你得到的是冲突而不是问题的解决方案。另一方面,如果D类派生自A类,则可以这样做。然而,

  • 现在继承必须是虚拟的。
  • 此解决方案调用可怕的钻石继承。注意事项。

答案 2 :(得分:0)

我知道这不是答案,而是更多的解决方法或黑客攻击。像这样:

template<class Parent>
class D : public Parent {
   static_assert(std::is_base_of<A,Parent>::value, "Not derived from A");
public:
   void f() { /*whatever you want here */ }
};

class X : public D<B> {
public:

};

class Y : public D<C> {
public:
};

除非是接口,否则我通常会避免多重继承。就像它在Java或PHP中使用它一样。

[编辑]结果:http://ideone.com/OtTZfh

答案 3 :(得分:0)

这就是你要做的事情:

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

class B : virtual public A{};
class C : virtual public A{};
class D : virtual public A { void f(){} };

class X : public D, public B {  };
class Y : public D, public C {  };

这里的关键是所有类都是从A派生virtual。如果省略virtual,X最终会得到两个A实例,一个继承自D,一个来自B,并且当然两者都必须有实施。这个virtual确保最后只有一个A实例,D中的一个实现就足够了。

答案 4 :(得分:0)

我没有将f 的实现移动继承层次结构,而是通过为{{1}引入一个新的公共基类来移动它 down }和B

C