我非常了解C(10年),但我是C ++新手。我得到以下的错误:
hw2.cpp: In function ‘int main()’:
hw2.cpp:337:7: error: no match for ‘operator=’ (operand types are ‘Graph’ and ‘Graph*’)
grph = new Graph(size);
^
hw2.cpp:337:7: note: candidate is:
hw2.cpp:17:7: note: Graph& Graph::operator=(const Graph&)
class Graph {
^
hw2.cpp:17:7: note: no known conversion for argument 1 from ‘Graph*’ to ‘const Graph&’
我的类和构造函数是:
class Graph {
//
// Class Graph -- contains the graph x, y of size Size showing connectivity
// (whether node X is connected to node Y) and the cost of
// the connection between X and Y.
//
private:
int nNodes;
vector<vector<int>> gph;
public:
//
// Constructors
//
explicit Graph(int size=50):nNodes(size){
gph = new int *[size];
for (int i = 0; i < size;i++)
gph[i] = new int[size];
}
//
// Destructors
//
~Graph(void){
retgph();
}
//
// Methods
//
void retgph(){
}
int getLength(
int x, // Node x
int y){ // Node y
return (gph[x][y]);
}
void setGraph(
int nodeX, // Node X
int nodeY, // Node Y
int value // Value to set it to.
){
gph[nodeX][nodeY]=value;
gph[nodeY][nodeX]=value;
return;
}
};
我的主要代码是:
int main(){
Graph abc; // graph object.
Open opn; // open set object.
int final; // final node which should be destination.
const int size = 10;
const int source=0; // source node.
const int dest=5; // destination node.
abc = new Graph(size);
opn = new Open(size);
请不要跟我说话,因为我不知道自己在做什么。我认为 ABC =新图(50) 应该实例化一个对象ABC,但图形是在构造函数Graph(int = size)中构建的,并且是GPH。当我说ABC.setNodeValue(1,2,3)时我访问了什么图表; ?类中的图GPH或另一个ABC实例化?如果它是一个实例化的(ABC)为什么GPH出现在Graph类中呢?我的想法是ABC是由方法操纵的(ABC.getNodeValue(47);)。类中的GPH是否只是作为实例化过程的模型出现在那里? GPH实际上也是INT ** GPH; 。您将给予我的任何帮助将不胜感激。
答案 0 :(得分:2)
当你最初说Graph abc;
时,你正在堆栈上构建一个Graph
对象(使用它的默认构造函数,在这种情况下是一个默认的转换构造函数,给出图形的大小50)。
然后尝试将类型Graph *
的内容分配给此变量,因为这是new
返回的内容(指向堆上新构造的对象的指针),这显然不是与变量的类型相同。这就是为什么编译器抱怨这些类型之间缺少operator=
(赋值运算符)的原因,并建议你打算使用复制赋值运算符,因为它与你的&#39;非常匹配。重新尝试,但仍然不正确。也许你正在尝试做以下事情:
const int size = 10;
Graph abc(size);
Open opn(size);
或许如果你确实需要通过指针存储它们:
const int size = 10;
Graph *abc = new Graph(size);
Open *opn = new Open(size);
// Do stuff...
delete opn;
delete abc;
答案 1 :(得分:0)
在Graph
课程中,gph
成员是包含std::vector
元素的std::vector
。 std::vector
是new[]
和delete[]
的包装器,因此无需直接使用它们来分配矢量。要在运行时更改std::vector
的大小,您可以使用其resize()
方法,例如:
class Graph {
private:
vector< vector<int> > gph;
public:
explicit Graph(int size=50) {
gph.resize(size);
for (int i = 0; i < size; ++i)
gph[i].resize(size);
}
/* You can even reduce the constructor even more,
using the constructor initialization list, if you
don't mind a little extra overhead temporarily...
explicit Graph(int size=50)
: gph(size, std::vector<int>(size) ) {
}
*/
/* not necessary to clear the vector during destruction,
it is handled automatic by the vector's own destructor...
~Graph() {
retgph();
}
*/
void retgph() {
gph.clear();
}
int getLength(int x, int y) {
return gph[x][y];
}
void setGraph(int x, int y, int value) {
gph[x][y] = value;
}
};
关于代码的其余部分......
new
运算符返回指向堆上分配的新实例化对象的指针。因此new Graph
分配一个Graph
对象,在其上调用Graph()
构造函数,并返回指向该对象的Graph*
指针。
您的编译器错误是因为您的abc
变量在堆栈上被声明为Graph
实例化对象而不是Graph*
指针。因此,当您调用abc = ...
时,实际上是在调用Graph::operator=()
复制赋值运算符(在这种情况下,编译器会为您自动生成)。该运算符期望const Graph&
(对常量Graph
对象的引用)作为输入,而不是Graph*
(指向Graph
对象的指针),因此“没有已知的转换Graph*
到const Graph&
“编译错误。
opn
变量的相同内容,使用Open
类。
将abc
和opn
变量更改为指针,并在访问这些对象的方法时将任何.
更改为->
。当你完成使用它们时,不要忘记delete
对象:
int main() {
const int size = 10;
Graph *abc; // pointer to graph object.
Open *opn; // pointer to open set object.
abc = new Graph(size);
opn = new Open(size);
//...
abc->setGraph(x, y, value);
opn->doSomething(parameters);
//...
delete opn;
delete abc;
}
或者,使用std::auto_ptr
或std::unique_ptr
为您处理delete
:
#include <memory>
int main() {
const int size = 10;
std::uninque_ptr<Graph> abc( new Graph(size) );
std::unique_ptr<Graph> opn( new Open(size) )
//...
abc->setGraph(x, y, value);
opn->doSomething(parameters);
//...
}
或者,只是继续在堆栈上实例化它们,但摆脱new
和delete
,当main()
退出时,让它们在超出范围时自毁:
int main() {
const int size = 10;
Graph abc(size);
Open opn(size);
//...
abc.setGraph(x, y, value);
opn.doSomething(parameters);
//...
}
现在,回答你的问题:
我认为ABC = NEW GRAPH(50)应该实例化一个对象ABC,但图形是在构造函数Graph(int = size)中构建的,并且是GPH。
abc = new Graph(50)
实例化一个构造函数值为50的新Graph
对象,然后将该对象指针指定给abc
。在内部,Graph
构造函数使用指定的gph
实例化size
向量。
当我说ABC.setNodeValue(1,2,3)时,我访问了什么图表; ?类中的图GPH或另一个ABC实例化了吗?
您正在访问abc
对象,该对象在内部访问gph
向量。
如果是实例化的(ABC),为什么GPH会出现在Graph类中呢?
它是abc
对象内部的一段数据。将Graph
视为信封,将gph
视为信封内的信息,将abc
视为握住信封的信号。每次调用new Graph
时,都会创建一个新的信封,其中包含一个新的gph
。
我的想法是ABC是由方法操纵的(ABC.getNodeValue(47);)。
是
类中的GPH是否只是作为实例化过程的模型出现在那里?
没有。这是被实例化的事情之一。
GPH实际上也是INT ** GPH;`
不在您展示的代码中。但逻辑上,这相当于2维std::vector
在运行时的行为 - 指针(在外部向量内)指向动态数组(外部向量管理的)指针(内部向量)到整数的动态数组(内部向量管理的内容)(内部向量包含的内容)。
上述代码的C等价物如下所示:
struct Graph {
int size;
int **gph;
};
struct Open {
//...
};
Graph* createGraph(int size=50) {
Graph *g = (Graph*) malloc(sizeof(Graph));
g->size = size;
g->gph = (int**) malloc(sizeof(int**) * size);
for (int i = 0; i < size; ++i)
gph[i] = (int*) malloc(sizeof(int) * size);
return g;
}
Open* createOpen(int size=50) {
Open *o = (Open*) malloc(sizeof(Open));
//...
return o;
}
void retGraph(Graph *g) {
for (int i = 0; i < g->size; ++i)
free(gph[i]);
free(g->gph);
g->gph = NULL;
g->size = 0;
}
void freeGraph(Graph* g) {
retGraph(g);
free(g);
}
void freeOpen(Open* o) {
//...
free(o);
}
int getLength(Graph *g, int x, int y) {
return g->gph[x][y];
}
void setGraph(Graph *g, int x, int y, int value) {
g->gph[x][y] = value;
}
void doSomething(Open *o, parameters) {
//...
}
int main() {
const int size = 10;
Graph *abc = createGraph(size);
Graph opn = createOpen(size)
//...
setGraph(abc, x, y, value);
doSomething(opn, parameters);
//...
freeOpen(opn);
freeGraph(abc);
}