3

假设我有三个类 , ,Solid定义如下:FaceEdge

class Solid{
    public:
        // perform an action on a single edge.
        void addFillet(int edgeNum);
        // perform an action on a single face
        void addBore(int faceNum);
        // perform an action on all faces and edges
        void move(Pos newPosition);
    private:
        std::vector<Edge*> edges;
        std::vector<Face*> faces;
};

class Face{
    public:
        // will modify a subset of edges
        virtual void changeHeight(int newHeight) = 0;
    private:
        int myNum;
        std::vector<Edge> edges;
}

class Edge{
    public:
        virtual void changeLength(int newLength) = 0;
    private:
        int myNum;
        int length;
}

在此示例中,Solid管理Edges 的“超集”。每个管理FaceSolid人都会有一个“子集” Solid.edges。此外,任何两个Solid.faces可能有一个共同的Edge.

我的问题:是否有任何设计模式或一般的面向对象原则来处理这种情况?如何管理 和 之间的Solid.edges关系Face.edges?进一步来说

4

1 回答 1

0

有很多方法可以管理这些类型的关系,但是如果您想要效率并且想要在边之间共享顶点并在面之间共享边,那么我建议您Solid应该拥有一个完整的Vertex和列表Edges

然后Edge对其顶点Face具有某种非拥有引用,对其边具有某种非拥有引用。这些非拥有引用可能类似于指针,但是您必须小心,不要通过重新分配顶点或边的主列表来使这些指针无效。如果您存储索引会更安全。但这确实意味着您必须参考以Solid找出顶点/边索引所指的内容:

class Solid {
  std::vector<Vertex> vertices;
  std::vector<Edge> edges;
  std::vector<Face> faces;

public:
  Solid(std::vector<Vertex> vertices) : vertices(std::move(vertices)) {}

  void addEdge(int vertex_index1, int vertex_index2) {
    edges.emplace_back(vertex_index1, vertex_index2);
  }
  void addFace(std::vector<int> edge_indices) {
    faces.emplace_back(std::move(edge_indices));
  }
  const Vertex &getVertex(int vertex_index) const { return vertices[vertex_index]; }
  const Edge &getEdge(int edge_index) const { return edges[edge_index]; }
};

class Edge {
  int vertex_first;
  int vertex_second;

public:
  Edge(int vertex_first, int vertex_second)
      : vertex_first(vertex_first), vertex_second(vertex_second) {}

  const Vertex &getVertexFirst(const Solid &solid) const {
    return solid.getVertex(vertex_first);
  }
  const Vertex &getVertexSecond(const Solid &solid) const {
    return solid.getVertex(vertex_second);
  }
};

class Face {
  std::vector<int> edge_indices;

  int getEdgeIndex(int face_edge_index) const {
    return edge_indices[face_edge_index];
  }

public:
  Face(std::vector<int> edge_indices) : edge_indices(std::move(edge_indices)) {}

  const Edge &getEdge(int face_edge_index, const Solid &solid) const {
    return solid.getEdge(getEdgeIndex(face_edge_index));
  }
};

现场演示

另一种方法是使用std::shared_ptrfor EdgeVertex但是您必须为动态内存分配和较差的数据局部性付费。

Solid存储对内部的反向引用FaceEdge更好地封装是很诱人的。您可以这样做,但随后vectorofFaceEdge有效地包含了许多重复的指针。如果这种封装对您很重要,我建议您创建某种包装类来处理包含原始边缘/面对象的边缘和面,以及对Solid.

于 2017-09-06T02:04:36.577 回答