C++: Objekte übergeben


  • Mod

    Ich glaube, pumuckl hat diese Fragen nicht gestellt, damit du zeigen kannst, dass du Arrays verstehst. Das glauben wir dir auch so.



  • SeppJ schrieb:

    Ich glaube, pumuckl hat diese Fragen nicht gestellt, damit du zeigen kannst, dass du Arrays verstehst. Das glauben wir dir auch so.

    Nein, das war für den TE, weil er sich sowieso nicht die Mühe macht, die Fragen zu recherchieren oder sich damit auseinanderzusetzen.

    Kannst es ja rauseditieren wenn du anderer Meinung bist. 🙂



  • Eigentlich ist schon alles gesagt, aber ich finde Sones Unterstellung unter aller Kanone und wollte nicht, dass die den Abschluss dieses Threads bildet...

    moon12 schrieb:

    Ein kleiner Hinweis, wie ich den Code zum Laufen bringen kann wäre zum Verständnis toll.

    Warum versuchst Du nicht erstmal eine Variante ohne Pointer. Also

    class A{
      B array_von_obj[5];
      //...
    };
    

    Dann wird einiges einfacher.
    Dann merk Dir, dass wenn Du arrays Übergibst diese zu einem Pointer auf das erste Element zerfallen. D.h. dass Array oben wird als B* übergeben - ohne Längeninformation! Die musst Du in einem zweiten Parameter mitschicken.
    D.h. Cs C'tor koennte so aussehen:

    class C{
      public:
        C(B*, size_t);
      //...
    };
    

    Wenn Du das alles hast und willst es dann mit Pointern versuchen: soll C eine Kopie der Pointer vorhalten, oder Pointer auf neue Objekte? Wer gibt den allozierten Speicher wieder frei?



  • @Sone:
    Das möchte ich dezent zurückweisen 🙂 Ich verstehe, dass eure Erfahrungen einschlägig sein mögen, ich habe aber z.B. in der Tat die geposteten Fragen zu beantworten versucht, nur war ich lange nicht so schnell wie Du ^^ Trotzdem Danke!

    Ich habe mir ein Konstrukt mit Vektoren gebaut und übergebe diese "by value", mit der Überlegung, die Klasse, die übergibt, vll später löschen zu können und alles als member in der annehmenden Klasse zu haben...
    Um Kritik zum Code wäre ich dankbar:

    #include<vector>
    #include"B.h"
    
    class A
    {
        vector<B> myBvector;
        vector<B> myAfunction()
        {
            for(...)
            myBvector.push_back(B(...));
            return myBvector;
        }
    };
    
    class B {};
    
    #include<vector>
    #include"B.h"
    
    class C
    {
        vector<B> newvector;
        C(vector<B>);
    };
    
    C::C(vector<B> fromA)
    {
        newvector = fromA;
    }
    
    int main()
    {
    A a();
    C c(a.myAfunction() );
    return 0;
    }
    

    Das ganze kann ich fehlerfrei kompillieren und liefert soweit ich das abschätzen kann, genau was ich wollte
    gruß, moon


  • Mod

    Sieht ok aus, guck dir aber noch dringend einmal an, was eine Initialisierungsliste ist.

    Wenn du noch Zuckerguss draufmachen möchtest: In C++ legt man sich bei Funktionsparametern ungern auf Containertypen fest. Stattdessen übergibt man (templatisierte) Iteratoren auf Anfang und Ende. Damit kann man beliebige Arten von Daten an C übergeben, nicht bloß vectoren. Und es entfällt eine unnötige, teure Kopie, von der ich mir gerade nicht sicher bin, ob sie wegoptimiert werden kann.
    Also zusammenfassend:

    template<typename Iterator> C(Iterator begin, Iterator end): newvector(begin, end) {}
    


  • stimmt etwas mit meinen Initialisierungen nicht?
    bei "..." steht natürlich in echt was anderes. Oder ist die Objektinstanziierung von a mit einem Funktionsaufruf als Paramter unschön?



  • moon12 schrieb:

    stimmt etwas mit meinen Initialisierungen nicht?

    Es tut schon stimmen.

    Aber es geht halt noch viel besser, und deswegen solltest du dir Initialisierungslisten anschaun'.

    @SeppJ: Sind Templates/Iteratorenmodell nicht ein wenig zu weit gegriffen?



  • stimmt wohl, ich hab zwar schon einiges zur Templateprogrammierung gelesen, aber das ist auf jeden Fall noch zu hoch. Ich denke ich machs mir einfacher, wenn ich das erstmal weglasse.

    noch eine Frage:
    Gehe ich richtig in der Annahme, dass der Speicher bei Programmende automatisch freigegeben wird und damit auch die im Vektor gespeicherten Elemente ?!
    D.h. ich muss nicht extra die Objekte im Vektor löschen (erase / delete)?


  • Mod

    Sone schrieb:

    @SeppJ: Sind Templates/Iteratorenmodell nicht ein wenig zu weit gegriffen?

    Ja, aber man kann ja mal einen Ausblick geben. Im Moment fehlt nur die Initialisierungsliste, damit es "ok" ist.

    moon12 schrieb:

    noch eine Frage:
    Gehe ich richtig in der Annahme, dass der Speicher bei Programmende automatisch freigegeben wird und damit auch die im Vektor gespeicherten Elemente ?!

    Jain. Automatisch freigegeben: Ja. Aber nicht zum Programmende, sondern dann, wenn der Vector aus dem Scope (Gültigkeitsbereich) geht.



  • moon12 schrieb:

    stimmt etwas mit meinen Initialisierungen nicht?

    Es stimmt in sofern nicht, das es keine Initialisierungen, sondern nachträgliche Zuweisungen sind. Im Konstruktorrumpf existieren die Werte bereits. Die einzige Stelle beim Konstruktor an der man Initialisieren kann ist die Initialisierungsliste.

    Das mag bei integralen Datentypen unproblematisch sein, bei Objekten rufst du so statt einen Konstruktor in der Regel 2 Konstruktoren und ein Zuweisungsoperator auf (was bei vielen und großen Objekten durchaus Unterschiede machen kann). Zudem kann man Referenzen und Konstanten als Membervariablen ausschließlich in der Initialisierungsliste setzen. Ebenso erzwingst du Standardkonstruktoren bei Objekten.

    class A {} // <-- Irgendein komplexes Element.
    
    class B
    {
      private:
        A a;
    
      public:
        // Fall 1: Ohne Initialisierungsliste.
        B()
        { // <-- Hier wird der Standardkonstruktor von a aufgerufen.
            a = A(123); // <-- Zuweisungsoperator + weiterer Konstruktoraufruf
        }
    
        // Fall 2: Mit Initialisierungsliste
        B()
        : a(123) // <-- Ein Konstruktoraufruf, zudem auch anderer als Standardkonstruktor möglich
        {
        }
    };
    


  • asc schrieb:

    a = A(123); // <-- Zuweisungsoperator + weiterer Konstruktoraufruf
    

    Das mit dem weiteren Konstruktoraufruf bezweifle ich. Die Temporary darf hier doch elidiert werden, oder nicht?

    Edit: Hmm, kann sein, dass das nur der Fall ist wenn ein entsprechender Ctor vorhanden ist...



  • Sone schrieb:

    asc schrieb:

    a = A(123); // <-- Zuweisungsoperator + weiterer Konstruktoraufruf
    

    Das mit dem weiteren Konstruktoraufruf bezweifle ich. Die Temporary darf hier doch elidiert werden, oder nicht?

    • Grundsätzlich gehe ich niemals von Compileroptimierungen bei Beschreibungen aus. Wenn diese greifen, schön und gut, aber zu wissen was im schlechten Fall passieren kann ist etwas anderes.
    • Kann ich mir das hier nicht ganz vorstellen (außer vielleicht durch C++11, da ich mich mit Movesemantik etc. noch nicht großartig beschäftigt habe - beruflich wäre ich froh wenn der verwendete Compiler schon mit dem Standard davor weitgehend kompatibel wäre [Ins Besondere bei Templates]).


  • asc schrieb:

    Sone schrieb:

    asc schrieb:

    a = A(123); // <-- Zuweisungsoperator + weiterer Konstruktoraufruf
    

    Das mit dem weiteren Konstruktoraufruf bezweifle ich. Die Temporary darf hier doch elidiert werden, oder nicht?

    • Grundsätzlich gehe ich niemals von Compileroptimierungen bei Beschreibungen aus. Wenn diese greifen, schön und gut, aber zu wissen was im schlechten Fall passieren kann ist etwas anderes.
    • Kann ich mir das hier nicht ganz vorstellen (außer vielleicht durch C++11, da ich mich mit Movesemantik etc. noch nicht großartig beschäftigt habe - beruflich wäre ich froh wenn der verwendete Compiler schon mit dem Standard davor weitgehend kompatibel wäre [Ins Besondere bei Templates]).

    😃


Anmelden zum Antworten