有没有办法用非常量变量初始化数组?

Is there a way to initialize an array with non-constant variables? (C++)

我正试图创建这样的类:

1
2
3
4
5
6
7
8
class CLASS
{
public:
    //stuff
private:
    int x, y;
    char array[x][y];
};

当然,直到我把int x, y;改为

1
const static int x = 10, y = 10;

这是不切实际的,因为我正试图从一个文件中读取x和y的值。那么,有没有任何方法可以用非包含值初始化数组,或者声明一个数组并在不同的语句中声明它的大小呢?我知道这可能需要创建一个数组类,但是我不确定从哪里开始,我不想在数组本身不是动态的时候创建一个二维动态列表,只是在编译时不知道它的大小。


使用矢量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <vector>
class YourClass
{
public:
    YourClass()
    : x(read_x_from_file()), y(read_y_from_file())
    {
        my_array.resize(x);
        for(int ix = 0; ix < x; ++ix)
            my_array[ix].resize(y);
    }

    //stuff

private:
    int x, y;
    std::vector<std::vector<char> > my_array;
};


编译器在编译时需要有类的确切大小,您必须使用新的操作符来动态分配内存。

将char数组[x][y];切换为char**数组;并在构造函数中初始化数组,不要忘记在析构函数中删除数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class MyClass
{
public:
    MyClass() {
        x = 10; //read from file
        y = 10; //read from file
        allocate(x, y);
    }

    MyClass( const MyClass& otherClass ) {
        x = otherClass.x;
        y = otherClass.y;
        allocate(x, y);

        // This can be replace by a memcopy
        for( int i=0 ; i<x ; ++i )
            for( int j=0 ; j<x ; ++j )
                array[i][j] = otherClass.array[i][j];
    }

    ~MyClass(){
        deleteMe();
    }

    void allocate( int x, int y){
        array = new char*[x];
        for( int i = 0; i < y; i++ )
            array[i] = new char[y];
    }

    void deleteMe(){
        for (int i = 0; i < y; i++)
           delete[] array[i];
        delete[] array;
    }

    MyClass& operator= (const MyClass& otherClass)
    {
        if( this != &otherClass )
        {
            deleteMe();
            x = otherClass.x;
            y = otherClass.y;
            allocate(x, y);
            for( int i=0 ; i<x ; ++i )
                for( int j=0 ; j<y ; ++j )
                    array[i][j] = otherClass.array[i][j];            
        }
        return *this;
    }
private:
    int x, y;
    char** array;
};

*编辑:我有一个复制构造函数和分配操作员


不是这样的,就像C++一样,C风格的数组大小必须在编译时知道,一些特定于供应商的扩展允许一定的运行时大小(以增强与C99的兼容性),但不是在你描述的情况下(如果你感兴趣的话,这里有一个描述)。最简单的方法是:

1
std::vector< std::vector<char> > array;

并在构造函数中应用大小:

1
2
3
4
array.resize(x);
for(std::vector< std::vector<char> >::iterator curr(array.begin()),end(array.end());curr!=end;++curr){
   curr->resize(y);
}

矢量与C型数组相比有很多优点,请参见此处


看看boost::multi_数组。


把所有的内存放到一个块中。因为它是私有的,所以您可以获取访问方法来检索正确的值。

快速示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <vector>
#include <iostream>

class Matrix
{
    public:
    class Row
    {
        public:
        Row(Matrix& p,unsigned int x)
            :parent(p)
            ,xAxis(x)
        {}
        char& operator[](int yAxis)
        {
            return parent.data(xAxis,yAxis);
        }
        private:
            Matrix&         parent;
            unsigned int    xAxis;
    };

    Matrix(unsigned int x,unsigned int y)
        :xSize(x)
        ,ySize(y)
        ,dataArray(x*y)
    {}

    Matrix::Row operator[](unsigned int xAxis)
    {
        return Row(*this,xAxis);
    }
    char& data(unsigned int xAxis,unsigned int yAxis)
    {
        return dataArray[yAxis*xSize + xAxis];
    }
    private:
        unsigned int xSize;
        unsigned int ySize;
        std::vector<char>   dataArray;
};


int main()
{
    Matrix      two(2,2);

    two[0][0]   = '1';
    two[0][1]   = '2';
    two[1][0]   = '3';
    two[1][1]   = '4';

    std::cout <<  two[1][0] <<"
"
;
    std::cout <<  two.data(1,0) <<"
"
;
}


您可以在构造函数中将内存分配给二维数组,并在析构函数中释放它。最简单的方法:

1
2
3
4
5
6
7
array = (char **)malloc(sizeof(char *) * x);
if (array) {
    for (i = 0; i < x; i++) {
        array[i] = (char *)malloc(sizeof(char) * y);
        assert(array[i]);
    }
}


不能使用非常量值(编译时)以声明方式分配或初始化全局或静态数组。但是,对于本地数组是可能的(C99可变大小的数组,因为它们的初始值设定项在每次执行函数时都在运行时运行)。

对于您的情况,我建议使用指针而不是数组,并在运行时动态创建实际数组(使用new)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class CLASS
{
public:
    CLASS(int _x, int _y) : x(_x), y(_y) {
       array = new char*[x];
       for(int i = 0; i < x; ++i)
           array[i] = new char[y];
    }
    ~CLASS() {
       for (int i = 0; i < x; ++i)
           delete[] array[i];
       delete[] array;
    }
    //stuff
private:
    int x, y;
    char **array;
};


如果要将动态大小的数组作为类成员,则需要对它进行数组new,并将该值赋给指针。char array[size]语法仅适用于静态大小的数组。

更好的是,您确实应该使用std::vector< std::vector >,现在很少有好的理由手动使用动态大小的数组。


如果在编译时不知道大小,则数组是动态的。你能做的就是让它保持静止,使其大于你所期望的最大尺寸。