在不同类中实现的纯虚函数的继承

时间:2013-06-10 10:01:19

标签: c++ inheritance

我正在尝试将c#项目转换为c ++。我正在尝试以下方法:

class IDocInterface
{
 public:
      // implemented in CSpecificDoc
      virtual bool CreateDoc() = 0;

      // implemented in COperations
      virtual void AddOperation() = 0;

      // implemented in CDoc
      virtual void Save() = 0;
};

class COperations
{
 public:
      void AddOperation() {}; // implementation for CDoc and derivates
};

class CDoc : public IDocInterface, public COperations
{
    public:
         void Save() {}; // implemented here
};

class CSpecificDoc : public CDoc
{
public:
      bool CreateDoc() {}; // implemented here
};

当我尝试做的时候:

  IDoc * pDoc = new CSpecificDoc(); 

我得到错误c2259无法通过以下成员来实例化抽象类: void IDocInterface :: AddOperations()是抽象的。

不知道我错过了什么。

我的继承结构在c#中工作正常,我使用“interface IDocInterface”和“abstract class CDoc”。

解决方案:

添加了:

class IOperations
{
 public:
     virtual void AddOperation() = 0;
}

然后将上面改为:

 class IDocInterface : public virtual IOperations
 {  
 public:
      // implemented in CSpecificDoc
      virtual bool CreateDoc() = 0;

      // implemented in CDoc
      virtual void Save() = 0;
 };

 class COperations : public virtual IOperations

尽管如此,我觉得有点奇怪的是,在没有IOperations类的情况下,整个事情在C#中工作得非常好......

3 个答案:

答案 0 :(得分:5)

除非COperations继承IDocInterface,否则其AddOperations()成员函数不会被视为与IDocInterface内定义的相同签名的虚函数有任何关联。在这种情况下,C ++编译器会抱怨缺少实现。

但是,继承IDocInterface中的COperations会创建多个继承相同成员函数的路径。这可能是一个问题,因为通过不同路径继承的函数,甚至是纯虚函数,都被认为是不同的(这与Java和C#的接口实现形成鲜明对比)。您可以通过标记继承virtual来解决此问题,如下所示:

class IWithOperations {
public:
      // implemented in COperations
      virtual void AddOperation() = 0;
};

class IDocInterface : public virtual IWithOperations
{
 public:
      // implemented in CSpecificDoc
      virtual bool CreateDoc() = 0;

      // implemented in CDoc
      virtual void Save() = 0;
};

class COperations : public virtual IWithOperations
{
 public:
      void AddOperation() {}; // implementation for CDoc and derivates
};

class CDoc : public virtual IDocInterface, public virtual COperations
{
    public:
         void Save() {} // implemented here
         virtual bool CreateDoc() = 0; // must be overridden
};

class CSpecificDoc : public virtual CDoc
{
public:
      bool CreateDoc() {} // implemented here
};

这是demo on ideone

答案 1 :(得分:0)

声明IDocInterface后,您无法实现不包含所有 CreateDocAddOperationSave的子类。

您需要重新实现它们,否则该类将被视为需要继承的抽象类以供使用。

如果您想在界面中使用可选的成员函数,可以像这样声明它们:

virtual bool CreateDoc() {} // note that you don't need to add ; here

并在必要时重新实施

class CDoc : public IDocInterface, public COperations
{
    public:
         // virtual is optional here but usually good for documentation (you can use override keyword instead if using C++11)
         virtual bool CreateDoc() { /* Default implementation */ } 
}

class CSpecificDoc : public CDoc
{
public:
      bool CreateDoc() { /* CSpecificDoc implementation */ }
}

可能是拼写错误,但您的COperations类不继承自IDocInterface,编译器不会将AddOperation方法视为IDocInterface中的IDocInterface方法的实现}。正如@dasblinkenlight在他的回答中所说,你将有多个IDocInterface继承,并且必须使用virtual关键字来避免多个class COperations: public IDocInterface { public: void AddOperation() {} // implementation for CDoc and derivates } 。这被称为继承钻石我认为(至少它是像在uni那样呈现给我们的。)

{{1}}

答案 2 :(得分:0)

我猜您需要在CDoc中重新实现AddOperation,因此它知道它与界面中的抽象相同:

class CDoc : public IDocInterface, public COperations
{
    public:
     Save() {} // implemented here
     virtual bool CreateDoc() = 0; // must be overridden
     void AddOperation() {
         COperations::AddOperation();
     }
}

或者你可以在c ++ 11中使用using语句......