C++ 中的对象指针的 2D 数组

2D Array of Object pointers in C++

本文关键字:2D 数组 指针 对象 C++      更新时间:2023-10-16

如何将指针的 2D 数组分配给对象?

目前我有:

文件.h

extern ClassName **c;

文件.cpp

ClassName **c;
int main(){
    // some stuff
    c = new ClassName*[sizex];
    for(int i = 0; i < sizex; ++i){
        c[i] = new ClassName[sizey];
    }
    for(int i = 0; i < sizex; ++i){
        for(int j = 0; j < sizey; ++j){
            c[i][j] = new ClassName();
        }
    }

它无法编译错误,指出使用 ClassName 和 ClassName* 的运算符 = 不匹配,查看错误是有意义的。但是,如果我要将 c[i][j] 的赋值更改为

ClassName cn();
c[i][j] = cn;

它给出了大量其他错误。数组的大小在运行时(从标准输入)之前无法知道,并且它也必须是 extern。在这种情况下,声明数组的正确方法是什么?

你必须像这样声明指针

extern ClassName ***c;

分配将如下所示

c = new ClassName**[sizex];
for(int i = 0; i < sizex; ++i){
    c[i] = new ClassName*[sizey];
    for(int j = 0; j < sizey; ++j){
        c[i][j] = new ClassName();
    }
}

如果您声明某种抽象类型的数组T,则可以自己正确定义 2D 数组。然后,您所需要的只是将T更改为ClassName *

至于这个宣言

ClassName cn();

然后它声明一个返回类型为 ClassName 且没有参数的函数。

ClassName *p1;

p1可以指向一个ClassName或一组ClassName

ClassName **p2;

p2可以指向一个ClassName*或一个ClassName*数组。

*p2可以指向一个ClassName或一个ClassName数组。

当您使用:

   c[i] = new ClassName[sizey];

您正在分配内存,以便c[i][j]可以容纳ClassName但不能容纳ClassName*

如果c[i][j] = ClassName();失败,并且您想使用 c[i][j] = new ClassName(); ,则必须将c声明为:

 ClassName*** c;

但是,为了不这样做,我强烈建议使用std::vector和智能指针。

 std::vector<std::vector<std::unique_ptr<ClassName>>> c;

前面的海报已经正确回答了使用 tripple 指针,但是为了你的理智和代码的清晰度,你可以使用几个简单的typedefs:

typedef ClassName* Row;
typedef Row* Matrix;
Matrix *M;  //equivalent to : ClassName ***M, 
            //check by substiting Matrix with Row* and Row with ClassName*
int main()
{
   M = new Matrix[numRows];
   for(int row = 0; row < numRows; ++row)
   {
        M[row] = new Row[numCols];
        for(int col = 0; col < numCols; ++j)
        {
            M[row][col] = new ClassName();
        }
    }
}

这样可以更好地传达您的意图,并且更容易推理。

您需要将类型更改为:类名 ***c; 正如来自莫斯科的弗拉德所提到的。

ClassName **c;
int main(){
    // some stuff
    c = new ClassName**[sizex];
    for(int i = 0; i < sizex; ++i){
        c[i] = new ClassName*[sizey]
    }
    for(int i = 0; i < sizex; ++i){
        for(int j = 0; j < sizey; ++j){
            c[i][j] = new ClassName();
        }
    }

您的用法也必须改变:

ClassName cn;
c[i][j] = new ClassName( cn );  // <-- this copy constructor would cause a memory leak (old pointer not deleted)
*(c[i][j]) = cn;                // <-- this would use the assignment operator.  May be weak performance.
ClassName & cn = *(c[i][]);     // <-- Allows you to work directly on the cell.

>ClassName **c是一个 2D 数组,即c[n][m] ClassName对象。

您试图将类型 ClassNamec[n][m]指定为类型 ClassName*new ClassName()

for(int i = 0; i < sizex; ++i){
    for(int j = 0; j < sizey; ++j){
        c[i][j] = *(new ClassName);
    }
}