首页 > 解决方案 > 使用 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很好,因为:

谁能解释为什么我必须创建一个显式实现才能使其工作。

标签: c++pure-virtual

解决方案


Node并且Graph是不相关的类。这使得Node::VisitGraph::Visit不同的不相关的成员函数。

两者都不能覆盖另一个。您似乎认为Graph::Visit比非纯虚拟的“更好” Node::Visit,因此应该覆盖它。但是没有客观原因。对于初学者,纯虚函数可以有一个定义:

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++的一个缺点是您实际上 . IMO 这是语言的一个怪癖(真的,应该可以保持它们不相关)。MSVC 有一个扩展,可让您以更细粒度的方式选择要覆盖的内容。Node::VisitGraph::VisitGraphNode3


推荐阅读