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]; }; |
当然,直到我把
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可变大小的数组,因为它们的初始值设定项在每次执行函数时都在运行时运行)。
对于您的情况,我建议使用指针而不是数组,并在运行时动态创建实际数组(使用
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; }; |
如果要将动态大小的数组作为类成员,则需要对它进行数组
更好的是,您确实应该使用
如果在编译时不知道大小,则数组是动态的。你能做的就是让它保持静止,使其大于你所期望的最大尺寸。