使用 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;
}
它不编译,但抱怨 GraphNode1
和 GraphNode2
是抽象的,因为 Node::Visit
是纯虚拟的。
我会假设 GraphNode1
和 GraphNode2
都很好,因为:
- 它们包含
Visit
的实现。
- 它们只包含
Visit
的单一实现,因此应该没有歧义。
任何人都可以解释为什么我必须创建一个显式实现才能使其工作。
Node
和 Graph
无关 类。这使得 Node::Visit
和 Graph::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::Visit
和 Graph::Visit
没有理由作为彼此的替代者进行交互。这就是为什么你需要明确地定义一个你自己的函数来作为覆盖*。
* C++ 的一个缺点是您实际上在 GraphNode3
中覆盖了 Node::Visit
和 Graph::Visit
。 IMO 这是语言的一个怪癖(真的,应该可以让它们不相关)。 MSVC 有一个扩展,允许您以更细粒度的方式选择要覆盖的内容。
考虑以下程序
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;
}
它不编译,但抱怨 GraphNode1
和 GraphNode2
是抽象的,因为 Node::Visit
是纯虚拟的。
我会假设 GraphNode1
和 GraphNode2
都很好,因为:
- 它们包含
Visit
的实现。 - 它们只包含
Visit
的单一实现,因此应该没有歧义。
任何人都可以解释为什么我必须创建一个显式实现才能使其工作。
Node
和 Graph
无关 类。这使得 Node::Visit
和 Graph::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::Visit
和 Graph::Visit
没有理由作为彼此的替代者进行交互。这就是为什么你需要明确地定义一个你自己的函数来作为覆盖*。
* C++ 的一个缺点是您实际上在 GraphNode3
中覆盖了 Node::Visit
和 Graph::Visit
。 IMO 这是语言的一个怪癖(真的,应该可以让它们不相关)。 MSVC 有一个扩展,允许您以更细粒度的方式选择要覆盖的内容。