Inheritance from empty base class in C++

2019-05-02 00:59发布

I want to make an empty base class called "Node", and then have other classes derived from this such as "DecisionNode" and "Leaf." It makes sense to do this so I can take advantage of polymorphism to pass these different kinds of nodes to methods without knowing at compile time what will be passed to the method, but each of the derived classes do not share any state or methods.

I thought the best way to implement this, without creating an additional pure virtual method in the base class, which would add clutter, would be to make the constructor pure virtual. In the header file for the class, "Node.h" I therefore wrote:

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

and in "Node.cpp" I wrote:

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

This implementation prevents Node from ever being instantiated by another class, since the only constructor is private and uses the pure virtual specifier to indicate that the class is abstract. However, this gives the compiler errors:

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

My question is: is there a neat way to make an empty abstract base class?

6条回答
家丑人穷心不美
2楼-- · 2019-05-02 01:28

In C++, constructors cannot be virtual. To prevent anyone from instantiating your base class, give it a protected constructor, like this:

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

It will not be abstract, but only derived classes will be able to create its instances.

查看更多
成全新的幸福
3楼-- · 2019-05-02 01:32

C++ doesn't support virtual constructor.

§ 12.1 Constructors

12.1.4 A constructor shall not be virtual (10.3) or static (9.4).

Below code won't compile:

virtual Node::Node() = 0;

My question is: is there a neat way to make an empty abstract base class?

Yes, make destructor a pure virtual function, also provides destructor function definition

class Node 
{
public:
    virtual ~Node()=0
    {
    }
};
查看更多
我想做一个坏孩纸
4楼-- · 2019-05-02 01:49

What you are trying to do is

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;

So you make a virtual distructor as ** virtual ~Node() = 0;**

查看更多
爷的心禁止访问
5楼-- · 2019-05-02 01:52

you can't make the constructor virtual. If no other pure virtual functions are needed you can make the destructor pure virtual:

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

Node::~Node()
{
  // Compulsory virtual destructor definition,
  // even if it's empty
}
查看更多
爱情/是我丢掉的垃圾
6楼-- · 2019-05-02 01:54

Create a virtual destructor and also provide an "empty" implementation.

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

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

The other alternative is to make the constructor protected, as others have commented. See also this question for some differences between the two. protected constructor versus pure virtual destructor

Edit Make sure you document why you are using the pure virtual destructor. The code by itself is cryptic in this regard and does not make it clear to someone who doesn't know about this "trick".

Edit 2 Your constructor should be protected, not private. You won't be able to inherit if your constructor is private.

查看更多
萌系小妹纸
7楼-- · 2019-05-02 01:55

Simply:

class Node 
{
protected:
    Node()
    {
    }
public:
    virtual ~Node()
    {
    }
}
查看更多
登录 后发表回答