2012-05-01 3 views
0

나는 그래프로 작동하는 프로그램을 작성 중이다. 두 가지 유형의 그래프를 다루고 있습니다 : "추상적 인 그래프", 가장자리가있는 추상적 인 꼭지점으로 구성되며, "평면 그래프"는 평면에서 x, y 좌표를 갖는 평면 그래프입니다 (사실 필자는 복잡한 접미사 z 그러나 그것은 중요하지 않습니다).C++에서 추상/구체적인 그래프 구현에 대해

필자는 Vertex.h 파일에서 다음과 같이 (추상) Vertex 클래스와 Planar_Vertex 파생 클래스를 작성하기로 선택했습니다.이 코드는 정확하게 내 코드가 아니며 약간 더 단순하게 만들고 프랑스어에서 번역했습니다.

class Vertex 
{ 
public: 
    Vertex(); 
    int get_label(); 
    void set_label(int label); 
    void add_neighbor(int label); 
    bool is_neighbor(int label); 
    // etc 
protected: 
    int _label; 
    std::vector<int> _list_neighbors; 
}; 


class Planar_Vertex : public Vertex 
{ 
    complex<double> _affix; 
public: 
    Planar_Vertex(); 
    Planar_Vertex(Vertex& V, complex<double> affix); 
    complex<double> get_affix(); 
    void set_affix(complex<double> affix); 
}; 

여기 내 주요 질문입니다. 내 Planar_Vertex (Vertex & V, 복합 접미사) 생성자에 다음과 같은 효과가 나타나기를 바랍니다. 1. 레이블과 이웃 목록이 V와 같고 접미사가 지정된 Planar_Vertex를 출력합니다. 지금까지 쉬운. 2. V가 정확하게이 새로운 객체의 근원 인 추상 꼭지점이되고 싶습니다. 내 MAIN.CPP 파일에 내가 쓴 경우 즉, 말,

Vertex V1; 
... 
Planar_Vertex V2(V1,z) 

는 내가 V2에 set_label의 사용()는 (예를 들어) V1에 영향을 미칠 것입니다 싶습니다. 이 생성자에서 볼 수있는 방법은 V (메모리)의 주소를 Planar_Vertex의 주소와 동일하게 만들고 (이전에 V에 할당 된 메모리를 비우는) 같은 것을 말하고 싶습니다. 분명히 메모리에있는 변수의 위치를 ​​변경할 수 없으므로 어떻게해야할지 모르겠다. 나는 C++에 비교적 익숙하다. 그리고 나는 새로운 배치, std :: move, rvalues ​​등등에 대해 잃어버린 독서문을 얻고있다. 내가 원하는 것을 어떻게하는 사람이 보이나요?

[편집 : 이미 구축 된 기본 클래스의 객체의 상단에있는 파생 클래스의 객체를 구축 할 수 있도록하려면, 요약합니다.]

가 좋아, 이후 나는 그래프에 대한 나의 구현에 대해 많은 사람들에게 말했고, 나는 당신에게 나머지에 관해 말할 것이라고 생각했다. 그래서 그것에 대해 당신의 의견을 말할 수있다. 첫 번째 질문에 대한 답이 이미 멋지다는 것을 알고 있다면 분명히 다음을 읽을 필요가 없습니다. 따라서 추상적 인 정점으로 구성된 "추상 그래프"와 평면 정점으로 구성된 평면 그래프를 다루고 있습니다.

여기처럼 내 Graph.h 파일이 어떻게 표시되는지를 보여줍니다 :

class Graph 
{ 
public: 
    Graph(); 
    virtual ~Graph(); 
    virtual std::vector<Vertex*> get_list_vertices(); 
    void add_edge(int label1, int label2); 
    virtual void add_vertex(Vertex&); 
    // etc 
}; 

class Abstract_Graph : public Graph 
{ 
    std::vector<Vertex*> _list_vertices; 
public: 
    Abstract_Graph(); 
    ~Abstract_Graph(); 
    std::vector<Vertex*> get_list_vertices(); 
    void add_vertex(Vertex& V); 
    // etc 
}; 

class Planar_Graph : public Graph 
{ 
    std::vector<Planar_Vertex*> _list_planar_vertices; 
public: 
    Planar_Graph(); 
    ~Planar_Graph(); 
    std::vector<Vertex*> get_list_vertices(); 
    std::vector<Planar_Vertex*> get_list_planar_vertices(); 
    void add_vertex(Planar_Vertex& V); 
    // etc 
}; 

내 생각이 기본 클래스 그래프를 통해 인스턴스되지 않습니다 것을,하지만 난이의 함수로 "추상 그래프 작업"을 구현할 수있을 것입니다 기본 클래스이며 Abstract_Graph 및 Planar_Graph 객체 모두에서 작동합니다. 이는 순수 가상 함수 get_list_vertices 덕택에 가능합니다. 이 일을하는 합리적인 방법입니까? 너 무슨 짓을 한거야?

미리 답변 해 주셔서 대단히 감사합니다.

답변

0

Planar_Vertex 클래스의 Vertex 객체에 대한 참조 (또는 포인터)를 이해하면 내가 원하는대로 할 수 있습니다.
아래로 잘라 데모 : 당신이 참조를 사용하는 경우

#include <iostream> 

struct Vertex { 
    int value; 
}; 

struct Planar_Vertex: public Vertex { 
    Vertex& vr; 
    Planar_Vertex(Vertex& v): vr(v) {} 
}; 

int main() 
{ 
    Vertex v; 
    v.value = 1; 
    std::cout << v.value << std::endl; 

    Planar_Vertex p = Planar_Vertex(v); 
    p.vr.value = 2; 
    std::cout << v.value << std::endl; 
} 

, 그것은 생성자 초기화 목록에 초기화해야합니다. 포인터를 사용하는 경우 초기화 방법에 유연성이 있지만 어디에서나 null 포인터에 대해 걱정해야합니다.

두 경우 모두 Vertex가 Planar_Vertex보다 오래 지속되도록해야합니다.

가 (또 다른 옵션은 Planar_Vertex의 생성자를 통해 초기화 Planar_Vertex –의 구성원으로 일반 정점 (안 참조 또는 포인터)를 가지고 있고, 당신이 필요로하는 곳을 사용하는 것입니다.이 수명 요구 사항을 담당하지만, 수도 코드에서 불가능할 수 있습니다.)

두 번째 부분에 대해서는 근본적으로 잘못된 것은 보이지 않지만 게시 한 내용만으로는 의견을 제시하기가 어렵습니다. 상속은 이것을 수행하는 한 가지 방법이며, 또 다른 방법은 템플리트를 사용하는 것입니다. 어떤 것이 더 적합한지는 정확한 요구 사항 (그리고이 두 가지 개념에 익숙 함)에 달려 있습니다.

+0

답변 해 주셔서 감사합니다. 저는 여러분이 설명하는 것처럼 두 개의 독립적 인 클래스 Vertex와 Planar_Vertex를 작성하는 것에 대해 생각해 보았습니다. 그러나 이것은 상속의 요점은 한 번만 추상 함수 (예 : add_neighbor 등)를 작성해야하기 때문에 내가 원하는 것을하지 않습니다. 추가적으로 필자가 그런 식으로 구현한다면 그래프에서 같은 문제가 발생할 것이다. 상속이 여기에서하는 자연스러운 일이라고 생각되지만 물론 잘못된 것일 수 있습니다. 템플릿에 관해서, 나는 그들에 대해 아무것도 모른다. – Seub

+0

위 예제는'Planar_Vertex : public Vertex'와 마찬가지로 잘 작동합니다. ''Vertex'의 꼭대기에''/ 주위에''Planar_Vertex' "를 만들고 싶다면 어떻게 보느냐에 따라"할 수 없다 "또는"선택의 여지가 없습니다 ". 모든'Planar_Vertex' 객체는 Vertex 꼭대기에 만들어져 있습니다. 그래서 이미 가지고 있습니다. 그러나 이미 구축 된 무작위'Vertex' 위에'Planar_Vertex'를 만들 수는 없습니다. – Mat

+0

(다른 말로하면 Vertex를 사용할 때마다 Planar_Vertex에 대한 참조 또는 포인터를 사용할 수 있습니다.) – Mat

관련 문제