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

时间:2014-12-11 19:07:36

标签: c++ arrays pointers

如何为对象分配2D指针数组?

目前我有:

file.h

extern ClassName **c;

file.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 *的operator =没有匹配,查看错误是有意义的。但是如果我要将c [i] [j]的赋值更改为

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

它提供了大量其他错误。 在运行时(从stdin读取)之前无法知道数组的大小,它也必须是extern。在这种情况下声明数组的正确方法是什么?

5 个答案:

答案 0 :(得分:4)

您必须声明指针

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且没有参数的函数。

答案 1 :(得分:2)

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;

答案 2 :(得分:1)

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

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();
        }
    }
}

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

答案 3 :(得分:0)

您需要将类型更改为: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.

答案 4 :(得分:0)

ClassName **c是一个二维数组,即c[n][m]ClassName个对象。

您试图将c[n][m]类型ClassName分配为new ClassName()类型的ClassName*

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