Frag zur Übergaben von Varibeln an Funktionen



  • Guten Tage.

    Ich habe da mal eine Frage zu den folgenden 3 Funktionsaufrufen :

    void Funktion(Datentyp variable)
    {
    ...
    }
    
    void Funktion(Datentyp *variable)
    {
    ...
    }
    
    void Funktion(Datentyp &variable)
    {
    ...
    }
    

    Kann mir jemand mal bitte den Unterschied zwischen den 3 Aufrufen erkläten. Also der erste Aufruf ist mir klar. Da wird die Variable einfach übergeben. Dabei wird eine lokale Kopie angelegt. Aber wo ist der Unterschied zwischen dem Zeiger und der Referenz und welches ist dei beste Metode im Bezug auf Speicherverbrauch. ich denke mal die erste scheidet aus. Danke für die Antworten



  • Ich würde empfehlen, den Post nochmal zu überarbeiten, die Rechtschreibfehler (die den Text teilweise unverständlich machen ->Mothe ?!?) zu eliminieren, die cpp-Tags zu korrigieren.
    Hast du denn in deinem Browser keinen Vorschau-Button?

    Dann sehen wir dass du dich bemühst, dann können wir uns auch bemühen 😉



  • Sehr schön, fast perfekt 😉 (Methode heißt das :p, aber egal)

    Es kommt halt einfach darauf an, was du bezwecken willst. Greift deine Funktion nur lesend auf das Objekt zu, übergibst du eine const-Referenz.
    Möchtest du eine Kopie des Objektes speichern, übergibst du eine const-Referenz.
    Soll die Funktion das übergebene Objekt verändern übergibst du eine Referenz.
    Soll es möglich sein, dass das übergebene Objekt optional ist, ist ein Pointer mit Default Wert "0" das passende.

    usw.

    Möctest du dich auf den kommenden Standard stützen, kannst du direkt als Value übergeben und mit std::move arbeiten, falls du eine "Kopie" ziehen willst.



  • Fischkopf2009 schrieb:

    Ich habe da mal eine Frage zu den folgenden 3 Funktionsaufrufen :

    void Funktion(Datentyp variable)
    

    Übergabe einer Kopie (call-by-value). Sofern der Ursprungswert nicht geändert werden soll, ist dies in der Regel der übliche Fall um integrale Datentypen (wie int, bool...) zu übergeben. Sollte es sich beim Datentyp aber um ein komplexeres Objekt handeln, kostet das Anlegen der Kopie Zeit (Hier greift man eher zu konstanten Referenzen, dazu aber anschließend mehr).

    void Funktion(Datentyp * variable)
    

    Hier übergibt man einen Zeiger. Ich werde hier keine Zeiger erklären, wenn du mit Zeigern nichts anfangen kannst, lies in einem x-beliebigen Buch nach. Dieser Weg wird in der Regel gewählt, wenn ein null-Wert zulässig ist, und das Objekt auf dem der Zeiger zeigt manipuliert werden soll.

    void Funktion(Datentyp & variable)
    

    Dies ist eine Referenzübergabe. Eine Referenz ist nur ein Aliasname für das übergebene Objekt, und du greifst damit direkt auf das ursprüngliche Objekt zu. Jede Änderung an der Referenzvariable schlägt sich somit direkt auf das übergebene Objekt durch. Dieser Weg wird üblicherweise genommen, wenn kein null-Wert zulässig ist (Referenzen müssen auf ein gültiges Objekt verweisen), und das Objekt in der Funktion manipuliert werden soll.

    Nun gibt es aber noch Abwandlungen von obigen, in Kombination mit dem Schlüsselwert const.

    void Funktion(Datentyp const & variable); // \ Identisch, ich bevorzuge die erste
    void Funktion(const Datentyp & variable); // / Variante, Gründe dazu später...
    

    Hier wird auch keine Kopie angelegt, man arbeitet ebenso auf der Referenz - ABER - die variable darf nicht verändert werden. Dieser Weg ist der übliche wenn man komplexe Objekte übergibt (und nicht kopieren will), diese aber nicht ändern soll.

    Zusätzlich kann man const aber auch mit Zeigern kombinieren, dies ist aber etwas komplexer, da man bei Zeigern sowohl den Zeiger (der Adresse) konstant definieren kann, als auch das Objekt auf das er verweist:

    const Datentyp * variable; // \ Beides identisch: Das Objekt, auf das
    Datentyp const * variable; // / gezeigt wird ist Konstant, nicht aber der Zeiger
    Datentyp * const variable; // Der Zeiger (die Adresse) ist konstant
    const Datentyp * const variable; // \ Beides identisch: Konstanter Zeiger
    Datentyp const * const variable; // / auf konstantes Objekt.
    

    So... nun kommt auch noch die Auflösung warum ich const im Zweifel hinter dem Datentyp stehen habe: Dann kann man sich merken das jeweils das davor stehende Konstant ist. Gelesen z.B. Datentyp-Konstante, Zeiger-Konstante.

    cu André
    P.S: Zum Speicherverbrauch ist zu sagen das eine Kopie immer so groß wie der Ursprungswert ist, eine Referenz kann intern als Zeiger behandelt werden, theoretisch muss eine Referenz aber keinen Speicherplatz kosten. Und ein Zeiger verbraucht genauso viel Speicher wie ein Zeiger auf dem System nunmal verbraucht (Auf üblichen Plattformen wohl in der Regel 32 oder 64 Bit - aber das ist wie gesagt Systemabhängig).



  • Ich möchte mich hiermit in aller Form für den sehr ausführlichen Beitrag bedanken . Ich habe es verstanden und werde es in meinen nächsten Projekten umsetzten .
    Danke nochmal :xmas1:


Anmelden zum Antworten