C++ C+中的对象指针的二维数组+;

C++ C+中的对象指针的二维数组+;,c++,arrays,pointers,C++,Arrays,Pointers,如何将2D指针数组分配给对象 目前我有: 文件.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;

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

目前我有:

文件.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();
        }
    }
它给出了过多的其他错误。
只有在运行时(从stdin读取)才能知道数组的大小,而且它必须是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();
    }
}

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

您需要将类型更改为: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**c;
int main(){
//一些东西
c=新类名**[sizex];
对于(int i=0;i
您的用法也必须更改:

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-cn;

c[i][j]=new ClassName(cn);//
ClassName**c
是一个二维数组,即
c[n][m]
对象

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

for(int i = 0; i < sizex; ++i){
    for(int j = 0; j < sizey; ++j){
        c[i][j] = *(new ClassName);
    }
}
for(int i=0;i
p1
可以指向一个
ClassName
或一个
ClassName
s数组

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

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

ClassName **p2;
使用时:

   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;
std::向量c;

之前的海报正确回答了关于使用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();
        }
    }
}
typedef ClassName*行;
typedef行*矩阵;
矩阵*M;//等价于:类名***M,
//通过将矩阵替换为行*和带有类名的行进行检查*
int main()
{
M=新矩阵[numRows];
对于(int行=0;行

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

如果在运行时之前无法知道数组大小,那么使用std::vector会更好。实际上,使用std::vector几乎总是更好。虽然我完全赞同您的评论,但它实际上并没有回答问题。请显示确切的错误消息。不要。为什么要这样做你?@kiss-o-matic它可能是
std::vector
,因为双指针仅在C型数组中是必需的。@lightnessrace他正在回答这个问题。当然,它可能需要一两段关于为什么这不是一个好方法的文章,但首先要回答这个问题。@Lightness在我展示的轨道上比赛正确的声明,而不是错误的声明。@Joseph在回答这个问题时排在第二位,之前他发出了一个巨大的警告,警告说所有这些都不应该出现在生产代码中。永远。仅仅因为它可以编译,并不意味着它在任何方式、形状或形式上都是可取的。@LightnessRacesinOrbit这是一个问答网站。不是一个专业的广告ice站点。@Daniel他的毛衣上已经有呕吐物了,妈妈的意大利面…,而且轻盈是对的,这应该鼓励更好的编程以及回答问题。矢量建议加1,希望智能指针加2。虽然我同意三指针是一种低劣的方法,但它不是禁止的,也不是不正确的。可怜的家伙显然,我正在尝试学习new[]并创建一个指针的二维数组。就我个人而言,我会使用封装在类中的唯一的数组或向量,访问器取(x,y)参数来解除指针的引用,但这不是问题所在。你为什么不给他解决方案,而不是批评其他人试图帮助他完成代码?同行评议是任何科学论述的关键部分。我建议你习惯于接受它。:)
 std::vector<std::vector<std::unique_ptr<ClassName>>> c;
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();
        }
    }
}