0

クラスのグラフ構造の実装に取り​​組んでいます。つまり、テストプログラムをコンパイルしようとすると、コピーコンストラクターを呼び出すと問題が発生します。

Graph.h:コピーコンストラクター内 `Graph :: Graph(Graph&)[with Object = int、Weight = int]':
gtest.cpp:16:ここからインスタンス化
Graph.h:129:エラー:`->'のベースオペランドの非ポインタ型が`Graph'
gtest.cpp:16:ここからインスタンス化
Graph.h:131:エラー:`->'のベースオペランドの非ポインタ型が`Graph'

問題のある行はここにあります:

template<typename Object,typename Weight>  //copy constructor 
Graph<Object,Weight>::Graph(Graph<Object,Weight>& G){

  for(int i=0; i<(G.edge).size(); ++i)   //129
    edge[i] = G.edge[i]; 
  for(int j=0; j<(G.vertex).size(); ++j) //131
    vertex[j] = G.vertex[j]; 

  counter = G.counter;  
}

...しかし、私は「->」ではなく「。」を使用しているので、これは私には意味がありません。私がポインタを扱っていない(または少なくとも私はそうではないと思う)のに、なぜ矢印について言及するのでしょうか?

参考までに、これまでのグラフの実装は次のとおりです(不完全です。欠落している部分と/ DONE? /コメントは無視してください)。

**編集:その前に、コピーコンストラクターが呼び出されたgtest.cppファイルを追加します。他のすべての部分は正常に機能します。

#include "Graph.h"

int main(){

Graph<int, int> g;


    g.insertVertex(8);
    g.insertVertex(256);
    g.insertVertex(32);
    g.insertVertex(7);
    g.insertEdge((g.vertices())[0], (g.vertices())[1], 457);
    g.insertEdge((g.vertices())[2], (g.vertices())[1], 457);
    g.insertEdge((g.vertices())[1], (g.vertices())[3], 457);

    Graph<int, int> g2 = g;

    g.print();
    }




#ifndef GRAPH_H
#define GRAPH_H

#include <list>
#include <vector>
#include <limits.h>
#include <algorithm>
#include <cmath>
#include <iostream> 

using namespace std;

template<typename Object,typename Weight>
class Graph{
  public:

  class Vertex;

  class Edge{
public:
    Edge(Vertex* v,Vertex* w,Weight setweight){
      start = v;
      end = w;
      v->edge.push_back(this);
      w->inedge.push_back(this);
      weight = setweight;
      explored = false;
    }
    Edge(){
      explored = false;
    }

        Weight weight;
        Vertex* start;
        Vertex* end;
        bool explored;
      };

      class Vertex{
    public:
        Vertex(Object setelement){
          level = 0;
          connectedcomponent = 0;
          element = setelement;
          back = NULL;
          explored = false;
        }
        Vertex(){
          level = 0;
          connectedcomponent = 0;
          back = NULL;
          explored = false;
        }
        Object element;
        vector<Edge*> edge;
        vector<Edge*> inedge;
        double value;
        unsigned int starttime, finishtime;
        unsigned int level;
        unsigned int connectedcomponent;
        float rank;
        Vertex* back;
      int color;
        bool explored;
      };    

      /////////////////////////////////////////////////////////////////////////
  private:

      vector<Edge*> edge;

      vector<Vertex*> vertex;

      unsigned int counter;

  public:
      /////////////////////////////////////////////////////////////////////////
      Graph();

      Graph(Graph& G);

      ~Graph();

      void reset();
      void resetBack();
      void resetValues();
      void resetLevels();
      void resetExplored();
      void resetConnectedComponents();

      vector<Vertex*> incidentVertices(Vertex* v);
      vector<Edge*> incidentEdges(Vertex* v);
      vector<Edge*> outgoingEdges(Vertex* v);
      vector<Vertex*> adjacentVertices(Vertex* v);
      unsigned int indegree(Vertex* v);
      unsigned int outdegree(Vertex* v);
      unsigned int degree(Vertex* v);
      Vertex* startVertex(Edge* e);
      Vertex* endVertex(Edge* e);
      // is there an edge from v to w ?
      bool isAdjacent(Vertex* v,Vertex* w);

      Vertex* insertVertex(Object o);
      void insertEdge(Vertex* v,Vertex* w,Weight t);
      void insertUndirectedEdge(Vertex* v,Vertex* w,Weight t);
      void removeVertex(Vertex* v);
      void removeEdge(Edge* e);

      unsigned int numVertices();
      unsigned int numEdges();
      vector<Vertex*> vertices();
      vector<Edge*> edges();

      void print();
      /////////////////////////////////////////////////////////////////////////

};



/*DONE?*/template<typename Object,typename Weight>
Graph<Object,Weight>::Graph() :edge(0), vertex(0), counter(0) {}


/*DONE?*/template<typename Object,typename Weight>  //copy constructor 
Graph<Object,Weight>::Graph(Graph<Object,Weight>& G){

  for(int i=0; i<(G.edge).size(); ++i)
//    edge[i] = G.edge[i]; 
  for(int j=0; j<(G.vertex).size(); ++j)
  //  vertex[j] = G.vertex[j]; 

  counter = G.counter;  
}

/*DONE?*/template<typename Object,typename Weight> //destrutor 
Graph<Object,Weight>::~Graph(){}  

/*DONE*/template<typename Object,typename Weight> 
void Graph<Object,Weight>::reset(){
  counter = 0;
  resetBack();
  resetValues();
  resetLevels();
  resetExplored();
  resetConnectedComponents();
}

/*DONE*/template<typename Object,typename Weight>
void Graph<Object,Weight>::resetBack(){
  for(unsigned int i=0;i<vertex.size();i++)
      vertex[i]->back = NULL;
}

/*DONE*/template<typename Object,typename Weight>
void Graph<Object,Weight>::resetValues(){
  for(unsigned int i=0;i<vertex.size();i++)
      vertex[i]->value = INT_MAX;
}

/*DONE*/template<typename Object,typename Weight>
void Graph<Object,Weight>::resetLevels(){
  for(unsigned int i=0;i<vertex.size();i++)
      vertex[i]->level = 0;
}

/*DONE*/template<typename Object,typename Weight>
void Graph<Object,Weight>::resetExplored(){
  for(unsigned int i=0;i<vertex.size();i++)
      vertex[i]->explored = false;
}

/*DONE*/template<typename Object,typename Weight>
void Graph<Object,Weight>::resetConnectedComponents(){
  for(unsigned int i=0;i<vertex.size();i++)
      vertex[i]->connectedcomponent = 0;
}

/*DONE?*/template<typename Object,typename Weight>  //concatenate incoming and outgoing edge lists and return vector of total inc. edges 
vector<typename Graph<Object,Weight>::Edge*> Graph<Object,Weight>::incidentEdges(Vertex* v){
    (v->edge).insert((v->edge).end(), (v->inedge).begin(), (v->inedge).end()); 
    return v->edge; 
}

/*DONE?*/template<typename Object,typename Weight> //return vector of outgoing edges
vector<typename Graph<Object,Weight>::Edge*> Graph<Object,Weight>::outgoingEdges(Vertex* v){
    return v->edge; 
}

/*DONE?*/template<typename Object,typename Weight>
vector<typename Graph<Object,Weight>::Vertex*> Graph<Object,Weight>::incidentVertices(Vertex* v){
  vector<Vertex*> result;
  for(int i=0; i<(v->incidentEdges()).size(); ++i){
    if((v->incidentEdges())[i].endVertex() == v) result.push_back((v->incidentEdges())[i].startVertex());
      else result.push_back((v->incidentEdges())[i].endVertex()); //edges incident on vertex could be either direction    
  } 
  return result;
}

/*DONE?*/template<typename Object,typename Weight>
vector<typename Graph<Object,Weight>::Vertex*> Graph<Object,Weight>::adjacentVertices(Vertex* v){
  vector<Vertex*> result;
  for(int i=0; i<(v->incidentEdges()).size(); ++i){
    if((v->incidentEdges())[i].startVertex() == v) result.push_back((v->incidentEdges())[i].endVertex()); } 
  return result;
}

/*DONE?*/template<typename Object,typename Weight>
unsigned int Graph<Object,Weight>::outdegree(Vertex* v){
  return (v->adjacentVertices()).size();    
}

/*DONE?*/template<typename Object,typename Weight>
unsigned int Graph<Object,Weight>::indegree(Vertex* v){
  return ((v->incidentEdges()).size()) - ((v->adjacentVertices()).size()); //I <3 parentheses 
}

/*DONE?*/template<typename Object,typename Weight>
unsigned int Graph<Object,Weight>::degree(Vertex* v){
  return (v->incidentEdges()).size();    
}

/*DONE?*/template<typename Object,typename Weight>
typename Graph<Object,Weight>::Vertex* Graph<Object,Weight>::startVertex(Edge* e){
    return e->start;    
}

/*DONE?*/template<typename Object,typename Weight>
typename Graph<Object,Weight>::Vertex* Graph<Object,Weight>::endVertex(Edge* e){
    return e->end;    
}

// is there an edge from v to w ?
/*DONE?*/template<typename Object,typename Weight>
bool Graph<Object,Weight>::isAdjacent(Vertex* v,Vertex* w){
  if(degree(v) <= degree(w)){ /*look in smaller incidence collection...but must fulfill directional requirements*/ 
    for(int i=0; i<(v->adjacentVertices()).size(); ++i) /*if directed edge is v to w, just check for adjacent vertex w*/ 
      if((v->adjacentVertices())[i] == w) return true; 
        else return false; }

  else{ /* if deg(w) < deg(v), look in w's incidence (not adjacency!) collection instead*/ 
    for(int i=0; i<(w->incidentEdges()).size(); ++i){ 
      if((w->incidentEdges())[i]->endVertex() == w) return true; /*badass-n. a person who keeps track of parentheses
                                  *like these and programs entirely in PuTTY
                                  *synonym: person too stubborn to take 5 minutes 
                                  *and learn Visual Studio*/  
        else return false; } 
  } 
}

/*DONE?*/template<typename Object,typename Weight>
typename Graph<Object,Weight>::Vertex* Graph<Object,Weight>::insertVertex(Object o){
  Vertex* v = new Vertex(o); 
  vertex.push_back(v); /*construct vertex and add it to Graph's vertex vector member*/ 
}

/*DONE?*/template<typename Object,typename Weight>
void Graph<Object,Weight>::insertEdge(Vertex* v,Vertex* w,Weight t){
  Edge* e = new Edge(v, w, t); 
  edge.push_back(e);  
}

/*DONE?*/template<typename Object,typename Weight>
void Graph<Object,Weight>::removeEdge(Edge* e){
  edge.erase(std::find(edge.begin(), edge.end(), e)); /*remove it from overall Graph's edge vector*/  
  ((edge.end()).incidentEdges()).erase(std::find(((edge.end()).incidentEdges()).begin(), ((edge.end()).incidentEdges()).end(), e)); 
    /*...also from end vertex's incidence list...in the least confusing code possible, of course...*/
  ((edge.begin()).incidentEdges()).erase(std::find(((edge.begin()).incidentEdges()).begin(), ((edge.begin()).incidentEdges()).end(), e));
      /*...and, finally, from begin vertex's incidence list*/ 
}

template<typename Object,typename Weight>
void Graph<Object,Weight>::insertUndirectedEdge(Vertex* v,Vertex* w,Weight t){
  Edge* dir1 = new Edge(v,w,t); 
  edge.push_back(dir1); //Hmm...should I push back one or both? This thing messes up the counts!
  Edge* dir2 = newEdge(w,v,t);
  edge.push_back(dir2);  
}

/*DONE?*/template<typename Object,typename Weight>
void Graph<Object,Weight>::removeVertex(Vertex* v){
  vertex.erase(std::find(vertex.begin(), vertex.end(), v)); /*remove it from overall Graph's vertex vector*/ 
  for(int i=0; i<(v->incidentEdges()).size(); ++i){
    if((v->incidentEdges())[i].start == v)
      (v->incidentEdges())[i].start = NULL; 
    else if((v->incidentEdges())[i].end == v)
      (v->incidentEdges())[i].end = NULL; }  
}

/*DONE?*/template<typename Object,typename Weight>
unsigned int Graph<Object,Weight>::numVertices(){
  return vertex.size(); 
}

/*DONE?*/template<typename Object,typename Weight>
unsigned int Graph<Object,Weight>::numEdges(){
  return edge.size(); 
}

/*DONE?*/template<typename Object,typename Weight>
vector<typename Graph<Object,Weight>::Vertex* > Graph<Object,Weight>::vertices(){
  return vertex; 
}

/*DONE?*/template<typename Object,typename Weight>
vector<typename Graph<Object,Weight>::Edge* > Graph<Object,Weight>::edges(){
  return edge; 
}

template<typename Object,typename Weight>
void Graph<Object,Weight>::print(){
  cout << "vertices:" << endl;
  for(unsigned int i=0;i<vertex.size();i++)
      cout << vertex[i]->element << endl;
      cout << "edges:" << endl;
  for(unsigned int i=0;i<edge.size();i++)
      cout << "(" << edge[i]->start->element << "," << edge[i]->end->element << ")" << endl;
}

#endif
4

3 に答える 3

0

おお。うわー。

結局のところ、私のディレクトリには同じ名前の「Graph.h」ファイルが 2 つありました。もちろん、1 つは古くて「->」の間違いがありました。私はそれを取り除きました(どうやってそこにたどり着いたのかもわかりません)、今ではすべて正常に動作しています。

助けてくれてありがとう、みんな!

PS-データ構造全体に「無向エッジ」メンバーを追加するだけで「insertUndirectedEdge」機能に対応することが有利だと思う人はいますか? 実装フレームワークは基本的にそれなしで提供され、インストラクターは、2 つの頂点 u と v の間に無向エッジを作成するには、2 つのエッジ (uv と vu) を使用する必要があると言いました。特に複雑になるカウント (頂点上のインシデント エッジの数など) を考慮すると、価値があるよりも面倒なようです。

于 2012-04-20T15:03:19.783 に答える
0

問題が発生した場所をもう一度確認してください。何かのようなもの、

template <typename T, typename K>
struct A
{
  T i;
  A(){};
  A(A&);
};

template <typename T, typename K>
A<T,K>::A(A<T,K>& that)
{
  i=that.i;
}

int main()
{
  A<int,int> _a;
  A<int,int> _b(_a);
  return 0;
}

標準であり、コンパイルもOKです。

于 2012-04-19T07:31:09.293 に答える
0

エラーはおそらく、Graph.h :129 および :131 で呼び出される gtest.cpp の 16 行目にあります。そこを見てください。

おそらく size() 関数に問題がありますか?

于 2012-04-19T10:48:17.140 に答える