我的拷贝构造函数有什么问题?

时间:2012-04-19 06:12:16

标签: c++ constructor

我正在为类实现Graph结构。简而言之,在尝试编译测试程序时,我对复制构造函数的调用会导致问题:

Graph.h: In copy constructor `Graph::Graph(Graph&) [with Object = int, Weight = int]':
gtest.cpp:16:   instantiated from here
Graph.h:129: error: base operand of `->' has non-pointer type `Graph'
gtest.cpp:16:   instantiated from here
Graph.h:131: error: base operand of `->' has non-pointer type `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;  
}

...但这对我没有意义,因为我使用的是“。”,而不是“ - &gt;”。如果我不是(或者至少我认为我不是)处理指针,为什么它甚至会提到箭头?

作为参考,我到目前为止的图表实现如下(它是不完整的;请忽略缺失的部分和/ DONE? / comments):

**编辑:在此之前,我将添加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

3 个答案:

答案 0 :(得分: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;
}

是标准的,编译好。

答案 1 :(得分:0)

错误可能在于gtest.cpp第16行,它在Graph.h:129和:131中调用。看看那里。

也许size()函数有问题?

答案 2 :(得分:0)

WOW。哇哇。

事实证明,我的目录中有两个同名的“Graph.h”文件。当然,一个人老了,有' - &gt;'错误。我摆脱了它(它甚至到达那里我不知道),现在一切都运行良好。

感谢所有人的帮助!

P.S .--有没有人认为通过简单地将“无向边”成员添加到整个数据结构来容纳“insertUndirectedEdge”函数会是有利的?实现框架基本上是在没有它的情况下给我们的,教师说我们需要使用两个边(uv和vu)在两个顶点u和v之间形成一个无向的边。也许我错过了什么,但这似乎就像它会比它的价值更麻烦,特别是考虑到计数(顶点上的入射边缘的数量等)会使它复杂化。