繁体   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