使用 using 实现纯虚函数

Implement pure virtual function with using

考虑以下程序

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

class Graph {
public:
  virtual void Visit();
};

class GraphNode1 : public Node, Graph {
};

class GraphNode2 : public Node, Graph {
    using Graph::Visit;
};

class GraphNode3 : public Node, Graph {
public:
    virtual void Visit() {
        Graph::Visit();
    }
};

int main()
{
  GraphNode1 a;
  GraphNode2 b;
  GraphNode3 c;
}

它不编译,但抱怨 GraphNode1GraphNode2 是抽象的,因为 Node::Visit 是纯虚拟的。

我会假设 GraphNode1GraphNode2 都很好,因为:

任何人都可以解释为什么我必须创建一个显式实现才能使其工作。

NodeGraph 无关 类。这使得 Node::VisitGraph::Visit 截然不同的不相关成员函数。

两者都不能覆盖另一个。您似乎认为 Graph::Visit 由于不是纯虚拟而在某种程度上比 Node::Visit “更好”,因此应该覆盖它。但是没有 objective 理由。对于初学者,纯虚函数可以有一个定义:

struct A {
    virtual void thing() = 0;
};

inline void A::thing() {}

其次,一个函数可以 成为纯虚拟的 当被覆盖时:

struct A {
    virtual void thing() {}
};

struct B : A {
    void thing() override = 0;
};

所以说真的,Node::VisitGraph::Visit 没有理由作为彼此的替代者进行​​交互。这就是为什么你需要明确地定义一个你自己的函数来作为覆盖*。


* C++ 的一个缺点是您实际上在 GraphNode3 中覆盖了 Node::VisitGraph::Visit。 IMO 这是语言的一个怪癖(真的,应该可以让它们不相关)。 MSVC 有一个扩展,允许您以更细粒度的方式选择要覆盖的内容。