在大学的C ++课程中,我必须实现一个定向加权图。作为内部表示,我必须实现一个二维数组,它存储有关图中顶点之间边缘的信息。
好吧,我已经用一个重载的[]运算符实现了一个C ++类“TwoDimArray”。
只要我在main()中实例化TwoDimArray的对象,它就能正常工作。但它并不是班级成员。
我的用于表示图形的类是“DirectedGraph”,并且具有类型TwoDimArray *的私有成员“adjacencyMatrix”。
在我的DirectedGraph类的构造函数中,我打算最初用零填充数组,表示“节点i和j之间没有边缘”。
好吧,这就是出错的地方。我可以写到坐标[0] [2](当用3个节点初始化图形时,所以数组应该有3x3个单元格)。当试图在地址[1] [0]处写入时,分配操作会因分段错误而崩溃。因此,赋值操作成功n次并从n + 1开始失败(其中n是顶点数)。任何想法我做错了什么?
My TwoDimArray Class(第一个标题,然后是实现):
#ifndef TWODIMARRAY_H_INCLUDED
#define TWODIMARRAY_H_INCLUDED
class TwoDimArray{
private:
int* pArr;
int rows;
int cols;
public:
TwoDimArray(int rows, int cols);
int* operator[](int row);
~TwoDimArray();
};
#endif // TWODIMARRAY_H_INCLUDED
实施:
#include <TwoDimArray.h>
TwoDimArray::TwoDimArray(int nrOfRows, int nrOfCols){
rows = nrOfRows;
cols = nrOfCols;
//allocate memory
pArr = new int[rows * cols];
}
int* TwoDimArray::operator [](int row){
return &pArr[row * cols];
}
TwoDimArray::~TwoDimArray(){
delete[] pArr;
}
定向图标题:
#define DIRECTEDGRAPH_H_INCLUDED
#include <string>
#include <list>
#include <Vertex.h>
#include <TwoDimArray.h>
using namespace std;
/**
* DOCUMENTATION
* ======================
* object oriented Implementation
* of the abstract
* Datatype Directed Graph
* as C++ class
*/
class DirectedGraph{
private:
int maxVertices;
list<Vertex> vertices;
TwoDimArray* adjacencyMatrix;
bool edgeExists(string srcName, string tgtName);
int vertexExists(string vName);
public:
//DirectedGraph();
DirectedGraph(int maxVertices);
~DirectedGraph();
void AddVertex(Vertex& v);
void AddEdge(Vertex& source, Vertex& target, int weight);
int getMaxVertices() const;
list<Vertex> getVertexNames()const;
void PrintGraph();
};
#endif // DIRECTEDGRAPH_H_INCLUDED
定向图实现(仅构造函数):
DirectedGraph::DirectedGraph(int maxV){
this->maxVertices = maxV;
//initialize the array
this->adjacencyMatrix = new TwoDimArray(maxV, maxV);
int i = 0;
int j = 0;
for(i = 0; i <= maxVertices - 1; i++){
for(j = 0; j <= maxVertices - 1; j++){
// ==> the fatal assignment
//fails at i = 1 and j = 0
*adjacencyMatrix[i][j]=0;
cout << "assigned " << i << " " << j << "with 0"<<endl;
}
}
}
有什么建议吗? 我想将类成员声明为TwoDimArray *而不是TwoDimArray是不行的,但是否则它不能编译。
我也尝试过:
DirectedGraph::DirectedGraph(int maxV){
this->maxVertices = maxV;
//try to instantiate TwoDimArray
TwoDimArray myArr(maxV, maxV);
this->adjacencyMatrix = myArr;
int i = 0;
int j = 0;
for(i = 0; i <= maxVertices - 1; i++){
for(j = 0; j <= maxVertices - 1; j++){
// ==> the fatal assignment
//fails at i = 1 and j = 0
myArr[i][j]=0;
cout << "assigned " << i << " " << j << "with 0"<<endl;
}
}
}
但它在同一点失败了。 我不太熟悉c ++中的指针逻辑我必须承认...
有什么建议吗?
提前谢谢 罗兰答案 0 :(得分:3)
您违反了Rule of Three。解决这个问题的最简单方法是避免直接分配内存:
class TwoDimArray{
private:
std::vector<int> arr;
int rows;
int cols;
public:
TwoDimArray(int rows, int cols) : arr(rows * cols);
int* operator[](int row) { return &arr[cols*row]; }
};
答案 1 :(得分:2)
一个问题是您没有为TwoDimArray
提供复制构造函数和赋值运算符。
这打破了以下几点:
TwoDimArray myArr(maxV, maxV);
this->adjacencyMatrix = myArr;
可能还有其他代码。