如何解决创建基于堆的2D数组而不使用双指针语法?
我需要声明一个2D数组作为类的成员变量。我不能使用STL(因此,没有向量),并且被要求避免使用双/三重指针。我希望能够使用下标符号来引用此2D数组中的元素,例如arr[0][0]
。由于数组的大小,还必须在堆上声明该数组。
由于我的要求,StackOverflow上的现有答案都无法满足我的需求。
我一直想做的是:
class MyClass {
public:
MyClass() : arr(new int[1000][2]) {}
// other stuff here
private:
int arr[1000][2];
};
编译该类后,我得到的错误是“无法初始化类型为int *
的左值的类型int[1000][2]
的参数”。显然,我可以使用指针语法解决此问题,但是如上所述,为了代码清晰起见,我被要求使用“数组语法”。 我希望对C ++有更好理解的人可以解释如何使用“数组语法”。
解决方法
当然,您可以在没有双/三指针的情况下执行此操作。您甚至可以在类声明中不使用任何指针的情况下执行此操作。但是首先让我们看一下更常见的方法。 2D数组是1D数组的简单扩展。
以标准方式开始,使用vector
对1000个int的1D数组进行此操作。指针arr
在堆栈上,但指向堆上1000个整数的数组。
class MyClass {
public:
MyClass() : arr(new int[1000]) {}
private:
int *arr;
};
以常规方式访问元素。例如arr[0]=42;
将其扩展到堆中的2D数组是上述内容的简单扩展。 您需要将成员变量声明为指向1D数组的指针,而不是基本类型。
class MyClass {
public:
MyClass() : arr(new int[1000][2]) {}
private:
int (*arr)[2];
};
类似地,您可以按照通常的方式引用2D数组的元素:arr[0][0]=42;
最后,除了new
所需的指针之外,还有一种方法可以完全消除指针。在这里,我们初始化一个参考。诀窍是在新的[1]
中添加第三级,以便*new
返回一个实际的2D int数组对象。从结构上讲,它与上面的指针版本没有什么不同,但是让我们直接初始化对2D int数组的引用。当然这不是一个常见的习惯用法,所以我会坚持使用ptr方法。
class MyClass {
public:
MyClass() : arr(*new int[1][1000][2]) {}
~MyClass() {delete[] arr;}
//private: // to test
int(&arr)[1000][2];
};
int main()
{
MyClass obj;
obj.arr[2][1] = 42;
}
,
当您的类中有一个数组,并且您使用new
创建该类的新实例时,该数组就在堆上。您仍然可以使用arr[i][j]
访问该数组。
为什么不做这样的事情?
class myClass {
public:
int arr[1000][2];
};
int main() {
myClass* test = new myClass;
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < 2; j++) {
test->arr[i][j] = 5;
}
}
}
,
您可以使用2个类来实现这一目标。
class BaseArray {
public:
int& operator[](int x) { return this->arr[x]; }
int operator[](int index) const { return this->arr[index]; }
int arr[2];
};
class myClass {
public:
myClass() {}
~myClass() {}
BaseArray& operator[](int index) { return this->arr[index]; }
BaseArray operator[](int index) const { return this->arr[index]; }
BaseArray arr[1000];
};
(可选)使用可以使用的模板来使此类更加动态。
template<class TYPE,int arraySize>
class BaseArray {
public:
TYPE& operator[](int x) { return this->arr[x]; }
TYPE operator[](int index) const { return this->arr[index]; }
TYPE arr[arraySize];
};
template<class TYPE,int dim1,int dim2>
class myClass {
public:
myClass() {}
~myClass() {}
BaseArray<TYPE,dim2>& operator[](int index) { return this->arr[index]; }
BaseArray<TYPE,dim2> operator[](int index) const { return this->arr[index]; }
BaseArray<TYPE,dim2> arr[dim1];
};
int main()
{
myClass<int,1000,2> myArray;
}
编辑
提供数组尺寸int arr[1000][2];
时,变量将自动分配到堆栈中。如果数组需要完全动态,则可以使用双指针int** arr = { nullptr };
并在构造函数中对其进行初始化,如下所示。
class myClass {
public:
myClass()
{
arr = new int* [1000];
for (int i = 0; i < 1000; ++i)
arr[i] = new int[2];
}
~myClass()
{
/* Make sure to delete or else it might flag a memory error. */
for (int i = 0; i < 1000; ++i)
delete[] arr[i];
delete[] arr;
}
int** arr = { nullptr };
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。