2

我正在尝试将 ac# 项目转换为 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# 中运行得这么好,这有点奇怪......

4

3 回答 3

5

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

但是,继承IDocInterfaceCOperations创建多个继承同一成员函数的路径。这可能是个问题,因为通过不同路径继承的函数,甚至是纯虚拟函数,都被认为是不同的(这与 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
};

这是关于 ideone 的演示

于 2013-06-10T10:13:26.253 回答
0

使用 的声明IDocInterface,您不能实例化不包含所有 CreateDoc和的子AddOperationSave

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

如果你想在你的接口中有可选的成员函数,你可以这样声明它们:

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. 正如@dasblinkenlight 在他的回答中所说,您将拥有多重IDocInterface继承,并且必须使用 virtual 关键字来避免拥有多个IDocInterface. 我认为这被称为继承钻石(至少它是像在大学那样呈现给我们的)。

class COperations: public IDocInterface
{
 public:
      void AddOperation() {} // implementation for CDoc and derivates
}
于 2013-06-10T10:07:32.723 回答
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 语句...

于 2013-06-10T10:08:13.687 回答