是否有设计模式或基本的面向对象原则来处理这种共享资源的情况?

时间:2017-08-01 13:11:57

标签: c++ oop design-patterns shared-resource

我们说我有三个课程,SolidFaceEdge定义如下:

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管理了一个&#39;超集&#39; Edge的。{ Face管理的每个Solid都有一个&#39;子集&#39; Solid.edges。此外,任何两个Solid.faces可能有一个共同的Edge

我的问题:是否有任何设计模式或一般面向对象的原则来处理这样的情况?如何管理Solid.edgesFace.edges之间的关系?更具体地说

1 个答案:

答案 0 :(得分:0)

有很多方法可以管理这些种类的关系,但是如果你想要效率并希望在边缘之间共享顶点并在面之间共享边缘,那么我建议你的Solid应该拥有{{1}的完整列表}和Vertex

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

Solid

Live demo

另一种方法是将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_ptrEdge,但是您必须为动态内存分配和较差的数据位置付费。

为了更好的封装,在VertexSolid内存储Face的反向引用很有诱惑力。您可以这样做,但Edgevector的{​​{1}}实际上包含了许多重复指针。如果这种封装对你很重要,我建议你创建一些包装类来处理包含原始边/面对象的边和面,以及对Face的反向引用。