Frage: Referenz als Returnwert einer Funktion

Debate general Frage: Referenz als Returnwert einer Funktion

  • Dienstag, 27. März 2012 16:44
     
      Enthält Code
    #include <iostream>
    #include <string>
    using namespace std;
    
    string &message(); //Return Wert referenzieren
    string nachricht();
    
    int main()
    {
    	cout << nachricht() << endl;	// Ausgabe: str - Nachricht
        cout << message() << endl;		// Ausgabe: str - Message
    	
    	nachricht() = " Text ABC";		// Anweisung
    	message() = " Text ABC";		// Anweisung -> Warum wird dieser String /Text ABC durch die Funktion selber nicht wieder überschrieben?
    
    	cout << nachricht() << endl;	// Ausgabe: str - Nachricht 
    	cout << message() << endl;		// Ausgabe: Text ABC
    
    	string eing;
    	cin >> eing;
    	return 0;
    }
    
    string nachricht() {
    	string str = " str - Nachricht " ;
    	return str;
    }
    
    string &message() {
    	static string str = " str - Message "; 
    	return str;
    }

    Im Code sind 2 Funktionen die als Returnwert einen Text/string zurückgeben.

    der Rückgabewert der Funktion message() ist referenziert, wenn ich nun eine Anweisung z.B. message() = " Text ABC"; mache und dann mit cout << message() << endl; das Ergebnis anzeige erhalte ich immer noch  " Text ABC" als Rückgabewert, obwohl die Fuktion ja "durchlaufen " wird und sich der Rückgabewert durch static string str = " str - Message "; und return str; sich der Rückgabewert , ändern sollte , oder wo habe ich meinen "Denkfehler" ?

    Schon mal Danke im vorraus ..

Alle Antworten

  • Mittwoch, 28. März 2012 09:24
     
      Enthält Code

    Das static sorgt dafür, dass die Variable str innerhalb von message nur einmalig initialisiert wird, und dann nie wieder! Dafür hat die Variable einen festen Platz im Speicher und kann mehrfach verwendet werden.

    int AnzahlAufrufe() {
      static int result = 0; //Einmalig initialisiert
      return ++result;
    }
    
    cout << AnzahlAufrufe(); //1
    cout << AnzahlAufrufe(); //2
    cout << AnzahlAufrufe(); //3

  • Mittwoch, 28. März 2012 12:33
     
     

    Danke für dein Antwort allerdings löst daß das Problem meiner Frage nicht.

    Die Variable str setzt man nur auf static damit beim verlassen der Funktion die Referenz &message()  nicht ins "Nirvana zeigt" da str (wenn es eine "normale" lokale Variable wäre) nicht mehr existiert, wenn die Funktion verlassen wird. Durch "static str.." existiert str nach verlassen der Funktion immer noch, somit existiert die Referenz für &message() weiterhin. (Bei deinem Beispiel verwendest du ja eine Funktion dessen Rückgabewert nicht referenziert ist)

    Vielleicht habe ich mich aber auch nur etwas unverständlich mit meiner Frage ausgedrückt.

  • Mittwoch, 28. März 2012 12:43
     
      Enthält Code

    Das macht aber kein Unterschied, ob mit oder ohne Referenz. Auf Grund von static wird es nur einmal initialisiert, beim ersten Aufruf.

    BTW.: static ist NICHT dazu da, damit die lokale Variable nach verlassen der Funktion nicht "ins Nirvana zeigt". static bedeutet so viel wie: "Nimm einen festdefinierten Speicherplatz". Ohne static hast du die Variable auf dem Stack, weswegen die Variable weg ist beim verlassen der Funktion. Mit static ist die Variable auf einem festen Platz, egal ob sich irgendwer in der Funktion aufhält oder nicht. Aber es ist immer immer immer nur EINE Variable. Egal wie oft Du die Funktion aufrufst, du hast immer nur einen Platz im RAM. Und sie wird auch nur einmal initialisiert.

    So wäre es das Ergebnis anders, weil die stringzuweisung nicht Teil der Initialisierung ist:

    string &message() {
    	static string str;
             str = " str - Message ";
    	return str;
    }


    • Bearbeitet GreatVolk Mittwoch, 28. März 2012 12:48 Begründung
    •  
  • Mittwoch, 28. März 2012 14:44
     
     

    Das ist zwar etwas OT und beantwortet Deine Frage nicht, aber allgemein ist die Rückgabe von Handles auf interne Datenstrukturen kein guter Programmierstil. Das verletzt nämlich eine der wichtigsten Regeln der objektorientierten Programmierung: die Kapselung der Daten und Implementierung der Algorithmen. Wenn das Projekt etwas umfangreicher wird und jeder über solche Referenzen Member ändern kann, wird das sehr fehleranfällig und schwer zu Debuggen. Wenn man Handles zurückgeben muss, dann als const &. Ansonsten Methoden erstellen, über die Daten geändert werden.

    stanilo

  • Donnerstag, 29. März 2012 06:08
    Moderator
     
     

    Hmm. Eigentlich müsstedas gehen und der string müsste sich bleibend verändern.

    Die Anwednung ist ja ähnlich wie in der Doku beschrieben:
    http://msdn.microsoft.com/en-us/library/z0c3dx2s(v=vs.100).aspx

    Geht das wirklich nicht?


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de


  • Donnerstag, 29. März 2012 06:18
    Moderator
     
      Enthält Code

    Ich habe das eben aus Neugierde ausprobiert.

    Das Programm arbeitet doch exakt wie erwartet.

    Was komt Dir denn hier komisch vor?

    message() = " Text ABC";		// Anweisung -> Warum wird dieser String /Text ABC durch die Funktion selber nicht wieder überschrieben?
    
    

    Es wird eine Referenz zurückgegeben. Diese Referenz wird mit dem neuen Wert belegt, der vortan gilt.

    Der staic selbst wurde nur/ wird nur einmal initialisiert.
    Das wurde ja auch von den anderen Usern schon beantwortet.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de

  • Donnerstag, 5. April 2012 14:52
    Besitzer
     
     
    ****************************************************************************************************************
    Dieser Thread wurde mangels weiterer Beteiligung des Fragestellenden ohne bestätigte Lösung abgeschlossen.
    Neue Rückfragen oder Ergänzungen zu diesem Thread bleiben weiterhin möglich.
    ****************************************************************************************************************

    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.