[英]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
};
使用IDocInterface
聲明,您無法實例化不包含所有 CreateDoc
, AddOperation
和Save
的子類。
您需要全部重新實現它們,否則該類將被視為需要繼承使用的抽象類。
如果要在接口中具有可選的成員函數,則可以這樣聲明它們:
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.