从函数返回多维数组

时间:2010-09-15 10:04:02

标签: c++ multidimensional-array

如何返回存储在班级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**作为回报

7 个答案:

答案 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 [,]而不是?