C++: Objekte übergeben
-
@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
-
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)?
-
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 KonstruktoraufrufDas 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 KonstruktoraufrufDas 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 KonstruktoraufrufDas 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]).
