C++ array = methodeMitArrayAlsRueckgabewert();?

Mika911

Captain
Registriert
Juni 2007
Beiträge
3.351
Hallo,
ich hab eine Anfängerfrage bzgl. C++. Ich arbeite mit Visual Studio2012.
Ich möchte den Rückgabewert einer Methode in einem Array speichern.
Die Methode gibt ein Array zurück bzw. einen Pointer darauf.
Ich versuch den Code mal verständlich wieder zu geben.
Die aktuelle Lösung sieht so aus:

Code:
int offsettemp[2];
offsettemp[0] = offsetErmitteln(wahlfeld)[0];
offsettemp[1] = offsetErmitteln(wahlfeld)[1];
offsettemp[2] = offsetErmitteln(wahlfeld)[2];
Code:
int* Spielmechanik::offsetErmitteln(int wahlfeld)
{
    int *aktivinaktiv = new int[2];
    ...
    return aktivinaktiv;
}

Nun hätte ich gerne eine elegantere Möglichkeit in der ich nicht jedes Element ansprechen muss.
Etwas wie:
Code:
int offsettemp[2];
offsettemp = offsetErmitteln(wahlfeld);

Ich hoffe es ist verständlich.
Die Lösung liegt bestimmt nahe aber ich seh sie nicht.


Mit freundlichem Gruß
Mika
 
Statt
PHP:
int offsettemp[2];
eben
PHP:
int* offsettemp;

Du gibst ja dein dynamisch erstelltes Array per Pointer aus der Funktion zurück, also musst du außerhalb der Funktion auch einen Pointer haben der den aufnimmt.

NICHT vergessen dieses Array irgendwann wieder freizugeben mit
PHP:
delete[] offsettemp;
sonst bekommst du Probleme.

Edit: Was auch geht ist, dass du das Array der Funktion übergibst, also
Code:
offsetErmitteln( int offset[], int wahlfeld )
Da Arrays in C++, wenn ich mich nicht irre, immer per Referenz übergeben und nicht kopiert werden, kannst du in deiner Funktion daran herumbasteln, aber die Änderungen sind dann auch außen sichtbar.
Also
Code:
int offsettemp[2];
offsetErmitteln( offsettemp, wahlfeld );
// offsettemp hat jetzt die in offsetErmitteln gesetzten Werte

Das erspart dir das new int[2] und das Achten auf delete[].
 
Zuletzt bearbeitet:
Man kann auch einfach eine Referenz des Arrays übergeben, in das geschrieben werden soll, an die Funktion übergeben.
Von der Performance her dürfte das dann auch ziemlich gut sein.
 
Vielen Dank für die schnelle Hilfe.
Die ganze Pointerlogik kann schonmal verwirren.
Edit.:Schon beantwortet.
 
Ja das meint er, hatte ich auch editiert, aber erst 5 Minuten später dran gedacht ohne die Seite zu aktualisieren :p

Bei void brauchst du am Ende aber kein return mehr.
 
Warum nicht einfach einen std::vector verwenden?

Code:
#include <vector>

std::vector< int > Spielmechanik::offsetsErmitteln()
{
    // Vector mit anfangs 2 Eintraegen anlegen.
    std::vector< int > offsets( 2 );

    // Werte eintragen.
    offsets.at( 0 ) = ...;
    offsets.at( 1 ) = ...;

    // Und an Aufrufer zurückgeben.
    return offsets;
}

Allemal bessers als mit new [] und delete [] rumzukaspern.


EDIT: Ok, der OP ist Anfänger, und um die technischen Kniffe zu verstehen, macht es vielleicht tatsächlich Sinn, erst mal mit "nackten" Arrays zu arbeiten. Für später würde ich dann aber auf jeden Fall vector (und die anderen Container-Klassen aus der Standardbibliothek) empfehlen.
 
Zuletzt bearbeitet:
auch wenn es hier wohl egal ist: lieber einen vector außerhalb der funktion anlegen und von der funktion verändern lassen (per referenz), als ihn zurückzugeben und dabei zu kopieren.
 
maxwell-cs schrieb:
auch wenn es hier wohl egal ist: lieber einen vector außerhalb der funktion anlegen und von der funktion verändern lassen (per referenz), als ihn zurückzugeben und dabei zu kopieren.

Wenn es ein sehr großer vector ist __UND__ der Rückgabewert nicht zur Initialisierung eines neu angelegten vectors dient, dann stimme ich zu. In allen anderen Fällen würde immer lieber Rückgabewerte als per Referenz übergebene out-Parameter wählen.

In einem Beispiel wie diesem hier:

Code:
std::vecor offsets = Spielmechanik::offsetsErmitteln();

darf der Compiler die Kopie wegoptimieren (und tut es in der Regel auch). Seit C++11 ist das aber selbst dann Wurscht, wenn er es nicht tut, denn hier greift dann der move constructor (welchen die Container-Klassen aus der Standardbibliothek meines Wissens alle implementieren).
 
ich schrieb ja schon, dass es hier wohl egal ist, aber das ist nunmal einer der fälle, wo man sich darauf verlässt, dass der compiler es schon noch repariert, wenn man es auch einfach direkt richtig machen könnte. das sollte man, und das ist nur meine meinung, vermeiden.

dass der move-konstruktor hier hilft, stimmt, aber wenn man sich die rückgabe von nichttrivialen objekten erstmal angewöhnt, macht man es vielleicht auch mal mit (z.b. selbstgeschriebenen) klassen, die ihn nicht implementieren.
 
maxwell-cs schrieb:
ich schrieb ja schon, dass es hier wohl egal ist, aber das ist nunmal einer der fälle, wo man sich darauf verlässt, dass der compiler es schon noch repariert, wenn man es auch einfach direkt richtig machen könnte. das sollte man, und das ist nur meine meinung, vermeiden.

Ehrlich gesagt fände ich es selbst dann nicht verkehrt, wenn man mal auf einen Fall trifft, in dem der Compiler die Optimierung aus irgend einem Grund unterläßt. Funktionen, die einfach nur Input-Werte entgegennehmen und ohne Nebeneffekte Output-Werte zurückgeben sind so viel intuitiver and angenehmer zu benutzen, daß ich den (meistens wahrscheinlich nicht spürbaren) Performance-Verlust in Kauf nehmen würde.
Sollte sich dann rausstellen, daß dies tatsächlich zu einem Flaschenhals in meinem Programm führt, könnte ich immer noch zurückrudern und die Funktionen von return auf Referenz-Output-Parameter umstellen.
 
Zuletzt bearbeitet:
Code:
int offsettemp[2];
offsettemp[0] = offsetErmitteln(wahlfeld)[0];
offsettemp[1] = offsetErmitteln(wahlfeld)[1];
offsettemp[2] = offsetErmitteln(wahlfeld)[2];
Wow. :eek:
Zähl nochmal deine Elemente :D
 
Oder ein guter Compiler:
Code:
test8.c:7:2: warning: array index 3 is past the end of the array (which contains 3 elements) [-Warray-bounds]
foo[3] = 3;
 
Zurück
Oben