2016-09-01 9 views
2

エッジの追加や削除などの非常に簡単な機能を持つ有向グラフのクラスを作成しようとしています。何らかの理由で、デフォルトコピーコンストラクタがその仕事をしていないので、私はその理由を知ります。ベクトルのベクトルが正しくコピーされない(C++)

main.cppに:

#include <iostream> 
#include "Graph.h" 

using namespace std; 


int main() 
{ 
    Graph g1(1); 
    g1.insertEdge(0, 0); 
    Graph g2(g1); 

    cout << (g1 == g2) << endl; // false 
    return 0; 
} 

Graph.h:私の主な機能には

#ifndef GRAPH_H_INCLUDE 
#define GRAPH_H_INCLUDE 

#include <vector> 

class Graph 
{ 
public: 
    typedef unsigned int vertex_t; 
    typedef std::vector< std::vector<bool> > edges_set_t; 

    vertex_t vertices; 
    edges_set_t edges; 

    Graph(vertex_t vertices = 0) 
     : vertices(vertices) 
    { 
     initEdges(); 
    } 

    void insertEdge(vertex_t v, vertex_t w) 
    { 
     edges[v][w] = 1; 
    } 

    bool hasEdge(vertex_t v, vertex_t w) const 
    { 
     return edges[v][w]; 
    } 


private: 
    void initEdges() 
    { 
     edges = std::vector< std::vector<bool> >(vertices); 
     while (edges.size() < vertices) 
      edges.push_back(std::vector<bool>(vertices)); 
    } 
}; 



bool operator==(const Graph& g, const Graph& h) 
{ 
    if (g.vertices != h.vertices) 
     return false; 

    for (Graph::vertex_t v = 0; v < g.vertices; ++v) 
     for (Graph::vertex_t w = 0; w < g.vertices; ++w) 
      if ((g.hasEdge(v, w) && !h.hasEdge(v, w)) || (!g.hasEdge(v, w) && h.hasEdge(v, w))) 
       return false; 

    return true; 
} 





#endif 

、私は一つの頂点にグラフを作成し、その上に自己ループを追加します。私は次に、デフォルトのコピーコンストラクタを使ってコピーしようとします。これは何らかの理由で正しい数の頂点を持つグラフを与えますが、エッジはまったくありません。私はこのコンストラクタを使用する場合

同じことが当てはまります。

Graph(const Graph& other) 
{ 
    vertices = other.vertices; 
    initEdges(); 
    edges = other.edges; 
} 

しかし、それは私が見つけることができない何らかの理由で、これで正常に動作します:

Graph(const Graph& other) 
{ 
    vertices = other.vertices; 
    initEdges(); 
    for (Graph::vertex_t v = 0; v < vertices; ++v) // no idea why a manual implementation is necessary 
     for (Graph::vertex_t w = 0; w < vertices; ++w) 
      if (other.hasEdge(v, w)) 
       insertEdge(v, w); 
} 
+3

'initEdges'はあなたが思っていることをしません - それは* empty *ベクトルのベクトルを作成します。 – Angew

+2

'edges = std :: vector >(頂点);'は後にedges.size()== vertices'を意味します。代わりに '予約'を呼び出すことを意味しましたか? – LogicStuff

答えて

2

このループ

while (edges.size() < vertices) 

は、あなたが呼び出すコンストラクタがベクトルの各要素に空のベクトルを追加するので、決して入力されません。あなたは正方行列を取得することを確認するために、

edges = std::vector< std::vector<bool> >(vertices, std::vector<bool>(vertices)); 

を使用これにより、不要なinitEdges()レンダリング、Graphのメンバーが使う初期リストに移動することができます。

また、常にedges.size()に等しいので、vertices変数を削除することができます。

あなたの比較演算子は、この行います

if ((g.hasEdge(v, w) && !h.hasEdge(v, w)) || (!g.hasEdge(v, w) && h.hasEdge(v, w))) 

条件はstd::vectorのサイズを比較しoperator ==を提供していますので、以下のように、あなたは比較演算子を書き換えることができます

if (g.hasEdge(v, w) != h.hasEdge(v, w)) 

と同等です:

bool operator==(const Graph& g, const Graph& h) { 
    return g.edges == h.edges; 
} 

Demo.

+0

ありがとう、私の問題の答えと他の提案の両方のために。 –

関連する問題