【问题标题】:C++ change a member of derived class to it's specialized versionC++ 将派生类的成员更改为其专用版本
【发布时间】: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


【解决方案1】:

一种选择是模板化 Graph 类。比如:

template<typename TVert> class Graph
{
    std::vector<TVert> vertices;
    // ...
};

这意味着特化可以声明为:

class GraphC : public Graph<VertexC*>
{
    // ...
};

不过,可能需要对 addVertex 方法做一些事情。可以这样声明:

void addVertex(int id)
{
    vertices.push_back(new TVert(id));
}

虽然这意味着 Graph 类的任何特化只能是包含一个构造函数的类型,该构造函数采用单个 int 参数。另一种方法是:

void addVertex(TVert vert)
{
    vertices.push_back(vert);
}

还要注意在 GraphC 的类声明中添加了 public 关键字。这将需要通过 GraphC 的实例使 Graph 的 addVertex 方法可用。

【讨论】:

    猜你喜欢
    • 2011-09-24
    • 1970-01-01
    • 2018-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 2016-10-10
    • 1970-01-01
    相关资源
    最近更新 更多