簡體   English   中英

從C ++中的空基類繼承

[英]Inheritance from empty base class in C++

我想創建一個名為“Node”的空基類,然后從其中派生出其他類,如“DecisionNode”和“Leaf”。 這樣做是有道理的,這樣我就可以利用多態將這些不同類型的節點傳遞給方法,而不必在編譯時知道將傳遞給方法的內容,但每個派生類不共享任何狀態或方法。

我認為實現這個的最好方法是,不在基類中創建額外的純虛方法,這會增加混亂,這將使構造函數變為純虛擬。 在該類的頭文件中,“Node.h”因此我寫道:

class Node {
 private:
  virtual Node();
};

在“Node.cpp”我寫道:

#include "Node.h"
virtual Node::Node() = 0;

此實現防止Node被另一個類實例化,因為唯一的構造函數是private,並使用純虛擬說明符來指示該類是抽象的。 但是,這會給編譯器錯誤:

Node.h:6:21: error: return type specification for constructor invalid
Node.h:6:21: error: constructors cannot be declared virtual [-fpermissive]

我的問題是:有一個簡潔的方法來創建一個空的抽象基類?

你不能使構造函數虛擬化。 如果不需要其他純虛函數,則可以使析構函數為純虛擬:

class Node
{
public:
    virtual ~Node() = 0;
};

Node::~Node()
{
  // Compulsory virtual destructor definition,
  // even if it's empty
}

C ++不支持虛擬構造函數。

§12.1構造函數

12.1.4構造函數不應為虛擬(10.3)或靜態(9.4)。

下面的代碼不會編譯:

virtual Node::Node() = 0;

我的問題是:有一個簡潔的方法來創建一個空的抽象基類?

是的,使析構函數成為純虛函數,還提供析構函數定義

class Node 
{
public:
    virtual ~Node()=0
    {
    }
};

創建一個虛擬析構函數,並提供“空”實現。

class Node {
    virtual ~Node() = 0;
}

Node::~Node() {}  // You will get linker error if you do not have this

另一種選擇是使構造函數受到保護,正如其他人所評論的那樣。 另請參閱此問題,了解兩者之間的一些差異。 受保護的構造函數與純虛擬析構函數

編輯確保記錄您使用純虛擬析構函數的原因。 代碼本身在這方面是神秘的,並沒有向不了解這個“技巧”的人說清楚。

編輯2您的構造函數應該受到protected ,而不是private 如果您的構造函數是private您將無法繼承。

在C ++中,構造函數不能是virtual 為了防止任何人實例化你的基類,給它一個受保護的構造函數,如下所示:

class Node {
protected:
  Node() {}
};

它不是抽象的,但只有派生類才能創建它的實例。

只是:

class Node 
{
protected:
    Node()
    {
    }
public:
    virtual ~Node()
    {
    }
}

你要做的是

class Node {
 private:
  virtual Node();
};
and in "Node.cpp" I wrote:

#include "Node.h"
// This is the error as your class name and function name i.e. same so compiler assumes 
// that this as a constructor and as per the c++ standard a constructor can not have 
// return type as well as can not be virtual
virtual Node::Node() = 0;

所以你將虛擬析構函數設為** virtual~Node()= 0; **

暫無
暫無

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

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