简体   繁体   English

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

[英]Inheritance of pure virtual functions implemented in different classes

I'm trying to convert ac# project to c++. 我正在尝试将ac#项目转换为c ++。 I'm trying the following: 我正在尝试以下方法:

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

When I try to do: 当我尝试做时:

  IDoc * pDoc = new CSpecificDoc(); 

I get error c2259 cannot intantiate abstract class due to folloing members: void IDocInterface::AddOperations() is abstract. 由于成员以下原因,我收到错误c2259无法实例化抽象类:void IDocInterface :: AddOperations()是抽象的。

Don't know what I'm missing. 不知道我在想什么。

My inheritance structure works fine like this in c# where i use "interface IDocInterface" and "abstract class CDoc". 我的继承结构在c#中像我这样正常工作,其中我使用“接口IDocInterface”和“抽象类CDoc”。

Solution: 解:

Added: 添加:

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

Then change above to: 然后更改为:

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

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

and

 class COperations : public virtual IOperations

Still, I think its a bit strange that the whole thing worked so nicely in C# without the IOperations class... 尽管如此,我觉得有些奇怪,没有IOperations类,整个事情在C#中表现得很好。

Unless COperations inherits IDocInterface , its AddOperations() member function is not considered related in any way to the virtual function with the same signature defined inside IDocInterface . 除非COperations继承IDocInterface ,否则不认为其AddOperations()成员函数与IDocInterface定义的具有相同签名的虚拟函数有任何IDocInterface In this case, C++ compiler will complain about a missing implementation. 在这种情况下,C ++编译器将抱怨缺少实现。

However, inheriting IDocInterface in COperations would create multiple paths of inheriting the same member function. 但是,在COperations继承IDocInterface将创建继承同一成员函数的多个路径。 This may be a problem, because functions, even the pure virtual ones, which are inherited through different paths are considered different (this is in sharp contrast to Java and C#'s implementations of interfaces). 这可能是一个问题,因为通过不同路径继承的函数(甚至是纯虚函数)也被认为是不同的(这与Java和C#的接口实现形成鲜明对比)。 You fix this problem by marking your inheritance virtual , like this: 您可以通过将继承标记为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
};

Here is a demo on ideone . 这是有关ideone演示

With your declaration of IDocInterface , you cannot instanciate a subclass that does not contain all CreateDoc , AddOperation and Save . 使用IDocInterface声明,您无法实例化不包含所有 CreateDocAddOperationSave的子类。

You need to reimplement them all, otherwise the class will be considered as an abstract class that needs to be inherited from to be used. 您需要全部重新实现它们,否则该类将被视为需要继承使用的抽象类。

If you wanted to have optional member functions in your interface, you can declare them like that: 如果要在接口中具有可选的成员函数,则可以这样声明它们:

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

And reimplement it where necessary 并在必要时重新实现

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 */ }
}

It may be a typo but your COperations class doesn't inherit from IDocInterface , the compiler will not consider the AddOperation method as an implementation of the one in IDocInterface . 这可能是一个错字,但你的COperations类没有继承IDocInterface ,编译器将不考虑AddOperation法作为一个在实现IDocInterface As @dasblinkenlight said in his answer, you will have multiple IDocInterface inheritance and will have to use the virtual keyword to avoid having several IDocInterface . 正如@dasblinkenlight在他的回答中所说,您将具有多个IDocInterface继承,并且将不得不使用virtual关键字来避免具有多个IDocInterface This is called inheriting in diamond I think (at least it was presented to us like that at uni). 我认为这称为“继承钻石”(至少像uni那样向我们提出)。

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

My guess is you need to re-implement AddOperation in CDoc so it knows it's the same as the abstract one in the interface: 我的猜测是您需要在CDoc中重新实现AddOperation,以便它知道它与接口中的抽象对象相同:

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

or you can use the using statement in c++11... 或者您可以在c ++ 11中使用using语句...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM