如何返回存储在班级private
字段中的多维数组?
class Myclass {
private:
int myarray[5][5];
public:
int **get_array();
};
// This does not work:
int **Myclass::get_array() {
return myarray;
}
我收到以下错误:
无法将
int (*)[5][5]
转换为int**
作为回报
答案 0 :(得分:23)
二维数组不会衰减到指向int的指针。它衰减到指向int数组的指针 - 也就是说,只有第一个维度衰减到指针。指针不指向int指针,当指针的大小增加时,它指向5个整数的数组。
class Myclass {
private:
int myarray[5][5];
public:
typedef int (*pointer_to_arrays)[5]; //typedefs can make things more readable with such awkward types
pointer_to_arrays get_array() {return myarray;}
};
int main()
{
Myclass o;
int (*a)[5] = o.get_array();
//or
Myclass::pointer_to_arrays b = o.get_array();
}
指向指针(int**
)的指针在单独分配每个子数组时使用(也就是说,你最初有一个指针数组)
int* p[5];
for (int i = 0; i != 5; ++i) {
p[i] = new int[5];
}
这里我们有一个包含五个指针的数组,每个指针指向一个单独的内存块中的第一个项目,共有6个不同的内存块。
在二维数组中,您将获得一个连续的内存块:
int arr[5][5]; //a single block of 5 * 5 * sizeof(int) bytes
你应该看到这些东西的内存布局完全不同,因此这些东西不能以同样的方式返回和传递。
答案 1 :(得分:17)
您可以返回两种可能的类型来提供对内部数组的访问。旧的C样式将返回int *[5]
,因为数组很容易衰变为指向第一个元素的指针,该元素的类型为int[5]
。
int (*foo())[5] {
static int array[5][5] = {};
return array;
}
现在,您还可以返回对内部数组的正确引用,最简单的语法是通过typedef:
typedef int (&array5x5)[5][5];
array5x5 foo() {
static int array[5][5] = {};
return array;
}
如果没有typedef,可能会更麻烦一点:
int (&foo())[5][5] {
static int array[5][5] = {};
return array;
}
C ++版本的优点是保持了实际类型,这意味着在调用者端已知数组的实际大小。
答案 2 :(得分:7)
要返回指向数组成员数组的指针,所需类型为int (*)[5]
,而不是int **
:
class Myclass {
private:
int myarray[5][5];
public:
int (*get_array())[5];
};
int (*Myclass::get_array())[5] {
return myarray;
}
答案 3 :(得分:2)
如何返回隐藏在私有字段中的多维数组?
如果它应该被隐藏,你为什么要首先归还它?
无论如何,你不能从函数返回数组,但是你可以返回指向第一个元素的指针。 5x5整数数组的第一个元素是什么?当然是一个5个整数的数组:
int (*get_grid())[5]
{
return grid;
}
或者,您可以通过引用返回整个数组:
int (&get_grid())[5][5]
{
return grid;
}
...欢迎来到C声明者语法地狱; - )
我可以建议std::vector<std::vector<int> >
或boost::multi_array<int, 2>
吗?
答案 4 :(得分:2)
更简单的是decltype(auto)
(自C ++ 14起)
decltype(auto) get_array() { return (myarray); } // Extra parents to return reference
然后decltype
(自C ++ 11起)(尽管应在方法之前声明成员)
auto get_array() -> decltype((this->myarray)) { return myarray; }
// or
auto get_array() -> decltype(this->myarray)& { return myarray; }
然后使用typedef方式:
using int2D = int[5][5]; // since C++11
// or
typedef int int2D[5][5];
int2D& get_array() { return myarray; }
因为常规语法非常难看:
int (&get_array())[5][5] { return myarray; }
使用std::array<std::array<int, 5>, 5>
(自C ++ 11起)将具有更自然的语法。
答案 5 :(得分:1)
我设法使用自动类型推导使此功能在C ++ 0x中工作。但是,如果没有这个,我就无法工作。在C ++中不能很好地支持本机C数组 - 它们的语法非常可怕。你应该使用包装类。
template<typename T, int firstdim, int seconddim> class TwoDimensionalArray {
T data[firstdim][seconddim];
public:
T*& operator[](int index) {
return data[index];
}
const T*& operator[](int index) const {
return data[index];
}
};
class Myclass {
public:
typedef TwoDimensionalArray<int, 5, 5> arraytype;
private:
arraytype myarray;
public:
arraytype& get_array() {
return myarray;
}
};
int main(int argc, char **argv) {
Myclass m;
Myclass::arraytype& var = m.get_array();
int& someint = var[0][0];
}
这段代码编译得很好。你可以在Boost(boost :: array)中获得支持整个shebang的预先编写的包装类。
答案 6 :(得分:-2)
将你的int更改为int [] []或尝试使用int [,]而不是?