Funktion gibt Vector zurück



  • dixidix schrieb:

    Also kann man das auch so mittels Memberfunktionen über Klassen machen.

    CKlasse c
    cout<<c.eineFunktion()[i]<<endl;
    

    Ja, das ist aber sehr ineffizient, weil bei jedem Aufruf der kompletet Vector neu erzeugt und kopiert wird.

    Genau das hatte ich mir schon gedacht. Worauf muss man dann achten?

    Darauf, dass das Objekt nach dem Funktionsaufruf noch weiterlebt.



  • dixidix schrieb:

    wird ein pointer zurückgegeben oder refenz sieht die sache anderes aus.

    Genau das hatte ich mir schon gedacht. Worauf muss man dann achten?

    Na ja, kleines Beispiel, was man nicht machen darf:

    int *myFunc() {
      int i=5;  //lokal angelegt
      return &i;
    }
    
    int *i=myFunc();  //Funktion wird beendet, der Pointer verliert seine Gültigkeit
    


  • Also so ?:

    int i=5;  //ausserhalb angelegt
    
    int *myFunc() {
    
      return &i;
    }
    
    int *i=myFunc();  //Funktion wird beendet, der Pointer bleibt gültig?
    

    LordJaxom schrieb:

    dixidix schrieb:

    Also kann man das auch so mittels Memberfunktionen über Klassen machen.

    CKlasse c
    cout<<c.eineFunktion()[i]<<endl;
    

    Ja, das ist aber sehr ineffizient, weil bei jedem Aufruf der kompletet Vector neu erzeugt und kopiert wird.

    Genau das hatte ich mir schon gedacht. Worauf muss man dann achten?

    Darauf, dass das Objekt nach dem Funktionsaufruf noch weiterlebt.

    Na gut, dürfte je nach Verwendungszweck zu beurteilen sein. Bei kleinen Vectoren wäre das sicher kein Problem, oder? Wie ginge es effizienter?



  • Globale Variablen solltest du vermeiden, wenn's geht. Also nein, so lieber nicht. Du kannst entweder die Variable erhalten, indem du sie in der Funktion mit static deklarierst (Google is your friend), oder du übergibst bereits einen Pointer an die Funktion, der dann gefüllt wird. Das ist in dem Fall sinnvoller (weil richtig!), als über den Rückgabewert zu gehen.

    void myFunc(int *i) {
      *i=5;  
    }
    
    int myIntVar;
    myFunc(&myIntVar);
    

    So hältst du dir auch den Rückgabewert frei, um z.B. einen Errorcode zurückzugeben. Außerdem kann eine Funktion auf diese Weise nicht nur einen, sondern gleich mehrere Werte "zurückgeben".



  • _matze schrieb:

    ...

    In C++ gibts Referenzen. Hier einen Pointer zu benutzen ist überflüssig:

    void someFunct(int &a)
    {
       a = 10;
    }
    
    //
    int var;
    someFunkt(var); //var ist nach dem Aufruf 10
    

    Um Fehler bei Funktionen mit Rückgabewerten zu signalisieren, gibt es Exceptions.



  • class MyData{
    ... 
     vector<int> data;
    ...
     vector<int> &Get(){ return data; }
    ...
    };
    
    MyData obj;
    
    int i= obj.Get()[x];
    

    Der vector existiert durch das MyData Objekt.

    Jetzt kann du die referenz des vetcor zurückgeben, weil der vector ja durch die Mydata Instanz exisitert auch nach dem Funktionsauruf.

    würdest du sowas machen

    vector<int> y= obj.Get();
    

    würde zwar der Vector zurüggeben werden, aber durch das "=" Zuweisung trozdm in y kopiert werden.

    Hier würde der Vector glaub sogar doppelt kopiert werden fällt mir ein:

    vector<int> func1(){
        vector<int> tmp;
        return tmp;
    }
    
    vector<int> h= func1();
    

    Rückgabe : Kopy Kosntruktor
    "=" : Zuweisungsoperator (Kopykonstruktor)



  • Tachyon schrieb:

    _matze schrieb:

    ...

    In C++ gibts Referenzen. Hier einen Pointer zu benutzen ist überflüssig

    An Referenzen stört mich, dass man an der aufrufenden Stelle nicht erkennen kann, ob sich der Wert der Variable nun verändert oder nicht. Vielleicht nur ein Detail, aber störend.

    Und im Beispiel ist die Übergabe eines Pointers doch unkritisch und genauso vertretbar wie eine Referenz, oder nicht?

    Zumal viele im Berufsleben eben nicht nur reines C++ programmieren können, sondern wie ich durchaus oft mit C-Code in Berührung kommen. Deshalb ist es in meinen Augen ratsam, sich auch mit Pointern auszukennen, um sich gut in bestehenden Code einarbeiten zu können bzw. auch mit einem C-Compiler nicht allein im Wald zu stehen. Zumal Pointer natürlich ebenso ein Bestandteil von C++ sind wie Referenzen.



  • _matze schrieb:

    An Referenzen stört mich, dass man an der aufrufenden Stelle nicht erkennen kann, ob sich der Wert der Variable nun verändert oder nicht. Vielleicht nur ein Detail, aber störend.

    Das erkennt man bei Pointern auch nicht.
    Aber nur mal so als Tip: Wenn Referenzen const sind, wird nichts geändert, wenn nicht, höchstwahrscheinlich schon.

    Der Rest Deiner Argumentation ist darin begründet, dass Du (sorry, dass ich das so sage) eher ein C mit Klassen Programmierer bist, als ein C++ Programmierer. Die meisten Deiner Posts hier zeigen das.
    Pointer nimmt man eigentlich nur, wenn auch nicht gültige Objekte übergeben werden sollen, soll heißen: 0-Zeiger. Ansonsten nimmt man doch besser Referenzen.

    EDIT: Und weil auch ein 0-Zeiger übergeben werden kann, ist Dein Beispiel eben doch nicht so unkritisch. 😉



  • Tachyon schrieb:

    Das erkennt man bei Pointern auch nicht.

    Na ja, ich sehe bei der Übergabe entweder den Adressoperator oder den "p"-Präfix, insofern sehe ich zumindest schon, ob eine Variable potenziell geändert wird.

    Tachyon schrieb:

    Der Rest Deiner Argumentation ist darin begründet, dass Du (sorry, dass ich das so sage) eher ein C mit Klassen Programmierer bist, als ein C++ Programmierer. Die meisten Deiner Posts hier zeigen das.

    Kein Problem, du hast ja Recht. Liegt eben daran, dass bei uns der Source zu 50% aus C-Code und zu 50% aus C-Code mit Klassen besteht. 🙂 Aber ich vermute, dass ich nicht der einzige bin, dem es so geht. Daher ist ein Anfänger in meinen Augen gut beraten, beides mal kennenzulernen.

    Tachyon schrieb:

    Pointer nimmt man eigentlich nur, wenn auch nicht gültige Objekte übergeben werden sollen, soll heißen: 0-Zeiger. Ansonsten nimmt man doch besser Referenzen.

    EDIT: Und weil auch ein 0-Zeiger übergeben werden kann, ist Dein Beispiel eben doch nicht so unkritisch. 😉

    Gut, an dem Null-Pointer-Argument ist was dran...



  • Zeiger würde ich dort einsetzen, wo mehr Flexibilität gefragt ist, also beispielsweise in Datenstrukturen oder bei dynamischer Speicherverwaltung. Also wenn nicht von Anfang an auf ein Objekt verwiesen wird oder das referenzierte Objekt wechselt.

    Wenn es möglich ist, verwende ich lieber Referenzen, vor allem bei Parameterübergabe. C++ hat da ja auch ganz besondere Regelungen bezüglich der Bindung von Const-Referenzen an temporäre Variablen. Damit werden einem z.B. auch Standardparameter mit Const-Referenzen ermöglicht, was bei Pointern nicht geht.


Anmelden zum Antworten