簡體   English   中英

在不同類中實現的純虛函數的繼承

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

我正在嘗試將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#中像我這樣正常工作,其中我使用“接口IDocInterface”和“抽象類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#中表現得很好。

除非COperations繼承IDocInterface ,否則不認為其AddOperations()成員函數與IDocInterface定義的具有相同簽名的虛擬函數有任何IDocInterface 在這種情況下,C ++編譯器將抱怨缺少實現。

但是,在COperations繼承IDocInterface將創建繼承同一成員函數的多個路徑。 這可能是一個問題,因為通過不同路徑繼承的函數(甚至是純虛函數)也被認為是不同的(這與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演示

使用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 正如@dasblinkenlight在他的回答中所說,您將具有多個IDocInterface繼承,並且將不得不使用virtual關鍵字來避免具有多個IDocInterface 我認為這稱為“繼承鑽石”(至少像uni那樣向我們提出)。

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

我的猜測是您需要在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語句...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM