【发布时间】:2018-11-20 21:31:15
【问题描述】:
假设我有两个类 - Graph 和 Vertex,它们具有表示一般 Graph 所需的一些基本成员和方法。它们已经完全实现并且非常适用于标准图。
class Vertex {
int id;
Vertex(int id) : id(id) {}
// ...
}
class Graph {
std::vector<Vertex *> vertices;
void addVertex(int id) {
vertices.push_back(new Vertex(id));
}
// ...
}
我想扩展这些类以添加一些与问题相关的功能。例如,我想要一个 Vertex 来存储它的颜色。这就是为什么我声明另一个名为VertexC 的类,它继承自Vertex 并添加了一个新成员。所以现在我想要一个专门版本的 Graph - GraphC 可以管理新的 VertexC 属性。
class VertexC: Vertex {
string colour;
string getColour() {
return colour;
}
}
class GraphC: Graph {
void doSomething(string colour) {
for(auto &v: vertices) {
if(v->getColour() == "red") // Do something...
}
}
}
但我不能这样做,因为 Graph::vertices 的类型是 Vertex * 而不是 VertexC * 所以他们不会有 getColour() 方法。有什么建议可以解决这个问题吗?
编辑:稍微更改了描述以更直接地介绍我的问题。
【问题讨论】:
-
使用它们的东西要么需要颜色,要么不需要。如果它需要颜色,它应该总是取一个顶点。如果不是,那么它不应该。通过在顶点对象列表上执行 dynamic_cast 以检查它们在运行时是否是 vertexc 对象,您正处于做一些糟糕的设计的风口浪尖。不要这样做。相反,答案是从 Graph 中取出顶点,使其成为仅接口类,然后制作一个颜色图和一个无颜色图,每个图都存储了他们需要的适当顶点类型。您还可以使用模板来指定要存储的 Vertex 类型
-
@xaxxon 一切听起来都很合理,但问题是 Graph 类已经实现,它提供了您可能需要使用图形的大量方法。您不认为提供与图本身无关的功能,而是与一些与问题相关的细节相关的功能应该在一些从 Graph 类继承主要实现的专用类中完成吗?
-
我建议搜索虚拟方法
-
"Graph 类已经实现" - 听起来你是在误用它作为基类。在听起来像 Graph 的设计目的和您尝试使用它的目的之间存在根本的设计分歧。不是每个类都是好的基类。
-
您的额外要求应在您的问题中详细说明,以激发您正在寻找的答案。但是,由于
Graph不能存储VertexC(因为addVertex的定义方式),GraphC的设计似乎有缺陷。
标签: c++ inheritance polymorphism