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