Frage

Ich habe versucht, ein Beispiel leben unter:

typedef struct point
{
    int x;
    int y;
} point;

void cp(point p)
{
    cout<<p.x<<endl;
    cout<<p.y<<endl;
}

int main()
{
    point p1;
    p1.x=1;
    p1.y=2;
    cp(p1);
}

Das Ergebnis, das ist gedruckt ist:

1
2

, das ist das, was ich erwartet hatte. Meine Frage ist: Hat Parameter p die vollständige Kopie des Objekts p1 erhalten? Wenn ja, dann frage ich mich, ob dies eine gute Praxis? (I angenommen wird, wenn die Struktur in der Größe groß wird, dies eine Menge Kopie Overhead erzeugen wird).

War es hilfreich?

Lösung

Es ist nichts falsch mit structs als Parameter übergeben. Alles wird von Wert in C ++ übergeben, so eine vollständige Kopie tatsächlich gemacht wird.

Die Struktur Sie in Ihrem Beispiel gab klein, so ist es wahrscheinlich kein Problem, wenn Sie es nach Wert übergeben. Aber wenn Sie mit größeren Datenstrukturen arbeiten, können Sie wollen, dass es durch Verweis übergeben.

Beachten Sie jedoch, durch Referenzmittel vorbei, wenn man die Struktur in Ihrer Funktion ändern, Ihre ursprüngliche Struktur wird geändert werden. Achten Sie darauf, das Schlüsselwort const in jedem Fall zu verwenden, in dem Sie die Struktur nicht ändern. Dadurch erhalten Sie eine sofortige Information über, wenn Ihre Funktionen, die Informationen nicht ändern oder nicht.

Ihr Beispiel zur Arbeit mit Verweis auf diese Weise modifiziert werden:

typedef struct point
{
    int x;
    int y;
} point;

void cp(const point& p) // You can know that cp doesn't modify your struct
{
    cout<<p.x<<endl;
    cout<<p.y<<endl;
}

void mod_point(point& p) // You can know that mod_points modifies your struct
{
    p.x += 1;
    p.y += 1;
}

int main()
{
    point p1;
    p1.x=1;
    p1.y=2;
    cp(p1);
    mod_point(p1);
    cp(p1); // will output 2 and 3
}

Andere Tipps

Ja, es ist nichts falsch mit diesem und ja, p ist eine vollständige Kopie p1. Ich würde keine struct mit zwei ints groß nennen, aber wenn die struct groß wird, und wenn Sie es nicht in der Funktion Körper zu verändern, braucht man bedenkt es durch konstante Referenz übergeben:

void cp(const point& p)
{
    // ...
}

Bevor ich eine Antwort auf Ihre Frage geben (Sie es am Ende dieses Beitrags finden), hier eine kurze Zusammenfassung der Möglichkeiten Sie haben Argumente für eine Funktion übergeben:


1. Copy-konstruierten Objekte (Pass-by-Wert):

void cp(point p);

Dies ist Pass-by-Wert. Ein temporäres point Objekt erstellt und kopier konstruiert aus, was auch immer point Objekt, das Sie in cp passieren. Sobald die Ausführung verlässt die cp Funktion wird das temporäre Objekt zerstört wird.

Beachten Sie, dass, da die Funktion auf einer Kopie arbeitet, was auch immer an die Funktion übergeben wurde, können Sie das lokale point Objekt ändern, so viel wie Sie wollen, das ursprüngliche Objekt des Anrufers wird nicht beeinträchtigt. Es gibt keine Möglichkeit, dieses Verhalten zu ändern, mit Pass-by-value-Parametern.


2. Verweise auf Objekte (Pass-by-reference):

void cp(point& p);

Dies ist pass-by-reference. Die eigentliche Aufgabe der Funktion übergeben verfügbar ist (und möglicherweise Änderungen vorbehalten) innerhalb der Funktion. Wenn Sie nicht möchten, dass die Funktion der Lage sein, das Objekt in gebenen zu ändern, erklärt die Parameter als const point&:

void cp(const point& p);

3. Zeiger auf Objekte (Pass-by-reference):

void cp(point* p);

Dies ist auch Pass-by-reference, mit einem paar feinen Unterschieden. Ein bemerkenswerter Unterschied ist, dass Sie einen Null-Zeiger auf die Funktion übergeben können. Dies ist nicht möglich mit Referenzen, weil Referenzen muss initialisiert werden und danach nicht mehr neu eingesetzt werden können. - Wie bei Referenzen, wenn Sie nicht zulassen cp wollen ändert die übergebenen in point, erklärt ihn als const:

void cp(const point* p);

Antwort auf Ihre Frage:

Pass-by-value-Parameter sind nicht von Natur aus schlecht in keiner Weise. Natürlich gibt es Typen, für die Kopie Konstruktion teuer ist (zum Beispiel sehr große oder komplexe Objekte), oder wo es bestimmte Nebenwirkungen (zum Beispiel mit std::auto_ptr). In diesen Fällen sollten Sie vorsichtig sein. Ansonsten ist es nur ein weiteres Merkmal von C ++, die seinen durchaus sinnvoll Gebrauch hat.

void cp(point p){
}

wird es von Wert

void cp(point *p){
}

wird es durch Bezugnahme

Genau wie jede andere Datenvariable.

In Java ist das Szenario anders. Passing Objekte immer durch Bezugnahme gehen.

Sie der Punkt struct Fall ist, passieren „Wert“, was bedeutet, dass die gesamte Struktur kopiert wird. Für große Datentypen, kann dies in der Tat langsam sein.

Sie können als Verweis das Objekt betrachten

void cp(point& p) // p may be altered!

oder sein konstante Referenz

void cp(const point& p) // p may not be altered!

Sehen Sie Möglichkeiten, Objekte zu vermeiden, indem sie Wert übergeben. Das Objekt ist nicht nur ‚kopiert‘, sondern ist so konstruiert kopieren. So beinhaltet diese Kopie Konstruktor aufrufen und die Kette der Kopierkonstruktoren, wenn Ihr Objekt zusammengesetzt ist, oder von mehreren Objekten abgeleitet. Pass durch Verweis, wenn möglich.

void cp (Punkt & p const) const {

    cout << p.x << endl;
    cout << p.y << endl;

}

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top