Rückgabe eines mehrdimensionalen Arrays von der Funktion

Lesezeit: 5 Minuten

Ruckgabe eines mehrdimensionalen Arrays von der Funktion
justin

Wie gebe ich ein mehrdimensionales Array zurück, das in a gespeichert ist? private Bereich meiner Klasse?

class Myclass {
private:
   int myarray[5][5];
public:
   int **get_array();
};

// This does not work:
int **Myclass::get_array() {
    return myarray;
}

Ich bekomme folgenden Fehler:

kann nicht konvertieren int (*)[5][5] zu int** im Gegenzug

  • was ist gitter sollte es nicht sein myarray?

    – Holzstok

    15. September 10 um 10:08 Uhr

  • Das Zurückgeben eines direkten Verweises auf ein privates Element ist möglicherweise nicht immer eine gute Idee – Sie brechen damit effektiv die Kapselung und ermöglichen jedem, auf Ihr privates Element zuzugreifen und es zu ändern. Dies kann in Ihrem Design akzeptabel sein oder nicht.

    – Peter Török

    15. September 10 um 10:11 Uhr


  • @MIkhail: Da Justin seit dem Posten dieser Frage nicht mehr online war, habe ich mir die Freiheit genommen, es zu beheben.

    – sbi

    13. November 10 um 12:34 Uhr

  • Sie können die Matrix-Bibliothek verwenden.

    – Amir Fo

    16. Juni 18 um 9:34 Uhr

1643905808 3 Ruckgabe eines mehrdimensionalen Arrays von der Funktion
Besucher

Ein zweidimensionales Array zerfällt nicht von Zeiger zu Zeiger auf Ints. Es zerfällt zu einem Zeiger auf Arrays von Ints – das heißt, nur die erste Dimension zerfällt zu einem Zeiger. Der Zeiger zeigt nicht auf int-Zeiger, die, wenn sie inkrementiert werden, um die Größe eines Zeigers vorrücken, sondern auf Arrays von 5 ganzen Zahlen.

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();
}

Ein Zeiger auf Zeiger (int**) wird verwendet, wenn jedes Subarray separat zugewiesen wird (das heißt, Sie haben ursprünglich ein Array von Zeigern).

int* p[5];
for (int i = 0; i != 5; ++i) {
    p[i] = new int[5];
}

Hier haben wir ein Array von fünf Zeigern, die jeweils auf das erste Element in einem separaten Speicherblock zeigen, insgesamt 6 verschiedene Speicherblöcke.

In einem zweidimensionalen Array erhalten Sie einen einzelnen zusammenhängenden Speicherblock:

int arr[5][5]; //a single block of 5 * 5 * sizeof(int) bytes

Sie sollten sehen, dass das Speicherlayout dieser Dinge völlig unterschiedlich ist und diese Dinge daher nicht auf die gleiche Weise zurückgegeben und weitergegeben werden können.

Es gibt zwei mögliche Typen, die Sie zurückgeben können, um Zugriff auf Ihr internes Array zu gewähren. Der alte C-Stil würde zurückkehren int *[5]da das Array leicht in einen Zeiger auf das erste Element zerfällt, das vom Typ ist int[5].

int (*foo())[5] {
   static int array[5][5] = {};
   return array;
}

Jetzt können Sie auch eine richtige Referenz auf das interne Array zurückgeben, die einfachste Syntax wäre über eine Typedef:

typedef int (&array5x5)[5][5];
array5x5 foo() {
   static int array[5][5] = {};
   return array;
}

Oder etwas umständlicher ohne typedef:

int (&foo())[5][5] {
   static int array[5][5] = {};
   return array;
}

Der Vorteil der C++-Version besteht darin, dass der tatsächliche Typ beibehalten wird, was bedeutet, dass die tatsächliche Größe des Arrays auf der Seite des Aufrufers bekannt ist.

  • Seien Sie jedoch vorsichtig, wie Sie diese Typedefs verwenden, manchmal: delete[] new array5x5() (sieht aus wie neu, ist aber wirklich neu[]).

    Roger Pate

    13. November 10 um 10:45 Uhr

Um einen Zeiger auf Ihr Array von Array-Mitgliedern zurückzugeben, ist der Typ erforderlich int (*)[5]nicht int **:

class Myclass {
private:
    int myarray[5][5];
public:
    int (*get_array())[5];
};

int (*Myclass::get_array())[5] {
    return myarray;
}

Wie gebe ich ein mehrdimensionales Array zurück, das in einem privaten Feld versteckt ist?

Wenn es versteckt werden soll, warum gibst du es überhaupt zurück?

Wie auch immer, Sie können keine Arrays von Funktionen zurückgeben, aber Sie können einen Zeiger auf das erste Element zurückgeben. Was ist das erste Element eines 5×5-Arrays von Ints? Natürlich ein Array von 5 Ints:

int (*get_grid())[5]
{
    return grid;
}

Alternativ könnten Sie das gesamte Array als Referenz zurückgeben:

int (&get_grid())[5][5]
{
    return grid;
}

…Willkommen in der Hölle der C-Deklarator-Syntax 😉

Darf Ich vorschlagen std::vector<std::vector<int> > oder boost::multi_array<int, 2> stattdessen?

Ruckgabe eines mehrdimensionalen Arrays von der Funktion
Jarod42

Einfacher wäre decltype(auto) (seit C++14)

decltype(auto) get_array() { return (myarray); } // Extra parents to return reference

dann decltype (seit C++11) (Member sollte aber vor der Methode deklariert werden)

auto get_array() -> decltype((this->myarray)) { return myarray; }
// or
auto get_array() -> decltype(this->myarray)& { return myarray; }

dann typedef weg:

using int2D = int[5][5]; // since C++11
// or
typedef int int2D[5][5];

int2D& get_array() { return myarray; }

da die reguläre Syntax sehr hässlich ist:

int (&get_array())[5][5] { return myarray; }

Verwenden std::array<std::array<int, 5>, 5> (seit C++11) hätte eine natürlichere Syntax.

Ich habe es geschafft, diese Funktion in C++0x mithilfe der automatischen Typableitung zum Laufen zu bringen. Ohne das schaffe ich es aber nicht. Native C-Arrays werden in C++ nicht sehr gut unterstützt – ihre Syntax ist äußerst abscheulich. Sie sollten eine Wrapper-Klasse verwenden.

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];
}

Dieser Code lässt sich gut kompilieren. Sie können eine vorgefertigte Wrapper-Klasse innerhalb von Boost (boost::array) erhalten, die den ganzen Kram unterstützt.

1643905809 706 Ruckgabe eines mehrdimensionalen Arrays von der Funktion
Harald

Ändern Sie Ihre ints in int[][]’s oder versuchen Sie es mit int[,] stattdessen?

  • … und int[][] sollte auch nicht gelten. In diesem Fall ist es wichtig, den Unterschied zwischen Arrays und Zeigern zu verstehen.

    – Besucher

    15. September 10 um 10:23 Uhr

  • @David: Eigentlich new int[5, 5] gültiges C++ ist, es macht einfach nicht das, was man denken könnte – es ist dasselbe wie new int[5] Danke an den Komma-Operator 🙂

    – fredoverflow

    15. September 10 um 10:38 Uhr


  • Ah, Entschuldigung, woran denke ich? C# evtl.? Haha, mein Fehler

    – Harald

    16. September 10 um 9:19 Uhr

.

757510cookie-checkRückgabe eines mehrdimensionalen Arrays von der Funktion

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy