【问题标题】:Inheriting both abstract class and class implementation in C++在 C++ 中继承抽象类和类实现
【发布时间】:2010-03-03 07:18:43
【问题描述】:

我希望这是一个简单的问题。

我可以继承一个抽象类和它的实现吗?也就是说,可以使以下工作吗?

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

class B {
   void func1() { /* implementation here */ }
}

class C : public A, public B {
}

我已经尝试了一些变体,并且收到了抱怨 C 类中未实现的方法的编译错误。但是,如果我能做到这一点,我可以节省大量重复的代码。有可能吗?


我通过创建一个名为 D 的“复合类”解决了这个问题,它继承自 A 和 B,但包含先前包含在 B 中的实现代码。这使我的继承模型不太干净,但它解决了这个问题而无需重复代码。而且,正如我在下面的 cmets 中所指出的,它使我的命名约定非常粗俗。

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

class B {
   // Other stuff
}

class D : public A, public B {
   void func1() { /* implementation here */ }
}

class C : public D {
}

【问题讨论】:

    标签: c++ abstract-class multiple-inheritance


    【解决方案1】:

    class B 不是您代码中class A 的实现。 Class B 应该继承自 class A 并且 func1 应该是虚拟的。只有在这种情况下,class B 才会实现class A。然后就不需要从 A 和 B 都继承了。

    class A { 
       virtual void func1() = 0; 
    }
    
    class B : public A {
       virtual void func1() { /* implementation is here */ }
    }
    
    class C : public B {
    }
    

    否则会得到未实现的纯虚函数func1

    【讨论】:

      【解决方案2】:

      让 B 从 A 继承。如果这不可能,使用虚拟继承也可能有效(我对此并不完全确定)。

      【讨论】:

      • 在这种情况下,A 和 B 是非常不同的类,除了少量的函数之外,真的没有任何共同之处。
      • 当你使用非虚继承时,C 会得到两个完全独立的 func1 函数。
      • 如果 B 没有从 A 继承,并且您试图通过在 C 中将它们混合在一起来使其覆盖 A 的功能,那么这将是非常糟糕的,钻石继承仍然需要 B 从 A 继承,它必须是:B类:虚拟A C类:虚拟A,B
      • 那个“漂亮的黑客”正是我想做的。
      【解决方案3】:

      如果您想在 C 类中重用 B 类的代码,请尝试执行以下操作:

      class C : public A, public B {
      void func1(){ B::func1(); }
      }
      

      【讨论】:

        【解决方案4】:

        正如基里尔指出的那样:你的前提是错误的。

        您的示例中的 B 类不继承 A 类(需要先声明它)。

        因此,对于编译器而言,B.func1() 与 A.func1() 完全不同。在 C 类中,它期望您提供 A.func1() 的实现

        上面有人发布了类似以下内容的内容:

        class C : public A, public B 
        {
              // implement A::func1()
              virtual void func1()
              { 
                   // delegate to inherited func1() in class B
                   B::func1(); 
              }
        }
        

        【讨论】:

        • 好吧,我想我们已经将问题缩小到找到一个好的命名约定之一: class LuaPolygonalGameObject : public GameObject, public Polygon, public LuaItem // Composite class yuck!但它确实编译!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-16
        • 1970-01-01
        • 2010-10-10
        相关资源
        最近更新 更多