实例化 2D 数组并在C++中使用它
Instantiating a 2d array and using it in C++
我很了解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会出现在类图中?我的想法是ABC是将被方法操纵的(ABC.getNodeValue(47);)。类中的 GPH 是否只是作为实例化过程的模型出现在那里?此外,GPH实际上是INT **GPH; 。您能给我的任何帮助将不胜感激。
当你最初说Graph abc;
你在堆栈上构造一个Graph
对象时(使用它的默认构造函数,在本例中是一个默认的转换构造函数,图形的大小为 50)。
然后,您尝试将类型为 Graph *
的内容分配给此变量,因为这是 new
返回的内容(指向堆上新构造对象的指针),它显然与变量的类型不同。这就是为什么编译器抱怨这些类型之间缺少operator=
(赋值运算符)的原因,并建议您改用复制赋值运算符,因为它与您尝试执行的操作非常匹配,但仍然不正确。也许您正在尝试执行以下操作:
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;
在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&
的转换"编译器错误。
对于使用 Open
类的 opn
变量也是如此。
将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
构造函数使用指定的size
实例化gph
向量。
当我说ABC.setNodeValue(1,2,3)时,我访问的是什么图; ?类中的图形 GPH 或其他 ABC 实例化?
您正在访问 abc
对象,该对象在内部访问gph
向量。
如果是实例化的一个(ABC),为什么GPH会出现在类图中?
它是位于abc
对象内部的一段数据。 把Graph
想象成一个信封,把gph
想象成信封里的东西,abc
想象成握着信封的手。 每次调用new Graph
时,都会创建一个新信封,其中包含一个新gph
。
我的想法是ABC是将被方法(ABC.getNodeValue(47);)操纵的。
是的。
类中的 GPH 是否只是作为实例化过程的模型出现在那里?
不。 这是正在实例化的事情之一。
此外,GPH实际上是INT **GPH;
不在你显示的代码中。 但从逻辑上讲,这相当于二维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);
}
- 2D数组来自文本输入,中间有空格
- 将值指定给向量(2D)的向量中的某个位置
- 如何使用用户输入在C++中正确填充2D数组
- 如何在C++中检查2D数组中负值的输入验证
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- 在 2D 向量中使用第三个 [ ] 有什么意义?
- 四边形的 2D 旋转
- 打印第二列时的2d字符矢量打印空间
- 如何将以逗号和空格分隔的整数读取到 2D 数组中?
- 如何在C++函数中声明静态 2D 数组?
- 我是 C++ 的初学者,我想知道如何在 2D 矢量中获取重复值
- 如何声明一个可以在整个程序中使用的全局 2d 3d 4d .. 数组(堆版本)变量?
- opengl glBegin(GL_LINES) 和 glBegin(GL_POINT) 在 2D 中不可视化点矢量
- 在C++中迭代 2D 容器的最干净方法
- 如何引用 2D 指针?
- 如何在 C++ 中使用它的构造函数初始化 unique_ptrs 的 2D 向量?
- C++动态安全 2D 交错阵列
- 如何在C++或OpenCV子矩阵中的2D子向量上使用OpenACC?
- 我已经阅读了很多关于 2d 数组的信息,但我在作业中使用它时遇到了麻烦
- 将 2D 推力::d evice_vector 复矩阵传递给 CUDA 内核函数