<vector> soll für jedes Element den Konstruktor aufrufen, aber wie?
-
öhm also im Standard Konstruktor meiner Klasse wird eine objekt vom Typ list<templ2> erzeugt, dass aber nach der oben beschriebenen Methode für alle Elemente von _liste gleich ist, aber nicht gleich sein sollte.
Bsp:
objektliste = new list<objekt>;MfG
Scarabol
-
...
-
Dann hab ich 0 Elemente im vektor..., wenn ich [] Klammern benutze.
MfG
Scarabol
-
Ja, hab schneller geschrieben als gedacht ...
-
Scarabol schrieb:
#include <vector> using namespace std; vector<templ> * _liste = new vector<templ>(50);Dieser Code ist ziemlich sinnlos. Entweder C Array oder std::vector
-
vll zeigst du mal deine klasse, die du als template-argument(immer templ genannt) verwendest. zumindest die deklaration, wenn die implementierung zu groß ist.
ich vermute das problem aber auch an einer anderen stelle.
bb
-
Scarabol schrieb:
öhm also im Standard Konstruktor meiner Klasse wird eine objekt vom Typ list<templ2> erzeugt, dass aber nach der oben beschriebenen Methode für alle Elemente von _liste gleich ist, aber nicht gleich sein sollte.
Bsp:
objektliste = new list<objekt>;Sag' ich doch. Klasse falsch entworfen. Das mit dem new gewöhnste Dir mal ganz schnell ab.
Es kann doch so einfach sein:
class object { public: int blah; explicit object(int j=0) : blah(j) {} }; class dings { list<object> objliste; public: void hau_rein(object const& o); }; void dings::hau_rein(object const& o) { objliste.push_back(o); } int main() { vector<dings> vec (50); vec[12].hau_rein(object(1729)); }Wenn Du nicht willst, dass mehrere Objekte einer Klasse Zeiger besitzen, die auf das gleiche Zeigen, dann definiere Dir Deinen eigenen Kopierkonstruktor und Zuweisungsoperator oder "schalte sie ab", indem Du sie als privat deklarierst (und gar nicht erst definierst).
kk
-
Wenn du tatsächlich Heap-Allokation für den Member brauchst, wirst du den Kopierkonstruktor so umstricken müssen, dass er eine Tiefenkopie macht. Ich habe aber die Vermutung, dass du statt
class templ { public: templ() : objektliste(new std::list<objekt>()) { } private: std::list<objekt> *objektliste; };schlicht
class templ { public: // ... private: std::list<objekt> objektliste; };schreiben solltest.
Der Grund, warum std::vector Kopien macht, ist übrigens, dass std::vectors betreffender Konstruktor so aussieht:
explicit vector(size_type n, const T& value = T(), const Allocator& = Allocator());...also
std::vector<templ> liste(50); // _liste ist ein reservierter Bezeichner!das selbe bedeutet wie
std::vector<templ> liste(50, templ(), std::allocator<templ>());und dementsprechend beim Aufruf ein temporäres Objekt erzeugt wird, das dann in alle Steckplätze des Vektors kopiert wird.
-
Hi,
wenn ich:
class templ { public: // ... private: std::list<objekt> objektliste; };schreibe.
Meckert der Compiler:
"Instanz von abstrakter Klasse, bla bla bla..."
Diesen Umstand (abstrakte Klasse) kann ich auch leider nicht beheben, da die Klasse zu der Grafikengine (Irrlicht) gehört, die ich benutze.MfG
Scarabol
-
Na, dann ist
objektabstrakt und dann kannst du davon keine Instanzen erzeugen..Dann wirst du wohl so etwas hier brauchen:
class templ { public: // ... private: std::list<objekt*> objektliste; };
-
Scarabol schrieb:
class templ { public: // ... private: std::list<objekt> objektliste; };schreibe, meckert der Compiler:
"Instanz von abstrakter Klasse, bla bla bla..."Das eine hat mit dem anderen nichts zu tun. Uns ging es um die Liste als echtes Datenelement Deiner templ-Klasse im Gegensatz zu einem Zeiger auf eine Liste als Datenelement.
Wenn jetzt "objekt" an sich abstrakt ist, funktioniert weder das eine noch das andere:
class templ { public: // ... private: std::list<objekt>* zeiger_auf_objektliste; };
-
Also benutze ich drakon's Ansatz?
MfG
Scarabol
-
In dem Fall lege ich dir Boosts Pointer-Container ans Herz, speziell boost::ptr_list. Alternativ std::list<std::tr1::shared_ptr<objekt> >. Dann musst du dich nicht selbst um die Speicherverwaltung kümmern.
-
Die Klassen die von der Grafikengine zur Verfügung gestellt werden, sind fast alle abstrakt. Wenn ich jetzt eine dieser Klassen in meiner eigenen verwenden möchte, bleibt mir doch nicht anderes übrig als den Pointer auf den Member "private:" zu deklarieren.
Im Konstruktor meiner Klasse erzeuge ich dann das eigentliche Objekt mit new.Versteh ich das jetzt richtig?
Edit Frage 2:
Ich habe eine Klasse, die den Pointer auf eine abstrakte Klasse als Member hat.
Wenn ich jetzt den Ctor definieren möchte, sollte der Pointer nicht nur kopiert werden sondern auch das Objekt auf das er evtl. zeigt.
Nur wie stell ich das an?
Wenn ich versuchemyklasse::myklasse(const myklasse& k) { _pointer_auf_abstrakt = new abstrakteKlasse(*k._pointer_auf_abstrakt); }Meint der Compiler "Instanz von abstrakter Klasse kann nicht erstellt werden."
MfG
Scarabol
-
@Scarabol:
Wenn du nur einen Zeiger auf eine Basisklasse hast (egal ob abstrakt oder nicht), aber das vollständige Objekt kopieren willst (dessen vollständigen Typ du nicht kennst)...
dann geht das nur, wenn der Entwickler der Basisklasse (und aller abgeleiteten Klassen) extra einen Mechanismus dafür vorgesehen hat.Der üblichste, mir bekannte solche Mechanismus wäre eine virtuelle Klon-Funktion in der Basisklasse, die dann in jeder abgeleiteten Klasse überschrieben wird.
Die Klon-Funktion gibt dir als Returnwert einen Basisklassen-Zeiger auf das kopierte, vollständige Objekt.Verwendung ist dann hübsch einfach:
myklasse::myklasse(const myklasse& k) { _pointer_auf_abstrakt = k._pointer_auf_abstrakt->Clone(); }Nur frage ich mich gerade, wieso du Objekte der Grafikengine kopieren willst/musst.
BTW: wenn es sich um Texturen/Meshes o.ä. handelt, dann kannst du die normalerweise "kopieren" indem du einfach ein neues Objekt über die Factory-Funktion der Engine erzeugst, und dann den Inhalt rüberkopierst.
Quasi (sinngemäss)
MyTexture::MyTexture(MyTexture const& other) { // neue Textur anlegen Size const size = other.m_engineTexture->GetSize(); m_engineTexture = other.m_engineTexture->GetEngine()->CreateTexture( size, other.m_engineTexture->GetPixelFormat()); // Daten rüberkopieren m_engineTexture->UpdateRect(Rect(Point(0, 0), size), other.m_engineTexture, Point(0, 0)); // oder wie auch immer man die Pixeldaten von einer Textur in eine andere kopiert }
-
Ich MUSS die Daten ja nicht kopieren, aber ein guter Kopierkonstruktor setzt voraus das ich es mache, oder?
Um bspw. die Skybox zu kopieren bzw. nach deiner Methode neu zu erzeugen sind einige Parameter notwendig, genau wie für andere Objekte. Daher müsste ich in fast alle meiner klassen dafür extra private Member zusätzlich definieren (Overhead).
Ich schau mal nach einer Klon Funktion...
Edit:
Die Engine hat tatsächlich für einige abstrakte Objekte eine clone Funktion. Leider kopiert die aber nicht das komplette Objekt sondern nur den Teil der geerbt wurde. Hilft mir also nicht weiter....MfG
Scarabol
-
Scarabol schrieb:
Ich MUSS die Daten ja nicht kopieren, aber ein guter Kopierkonstruktor setzt voraus das ich es mache, oder?
Wieso willst du kopieren?
Wieso meinst du dass du einen Copy-Ctor brauchst?
-
Na, weil vector<templ> den Ctor benutzt. Muss ich ihn auch definieren, damit ich korrekte templ Objekte erhalte.
MfG
Scarabol
-
Und wieso willst du
vector<T>verwenden?
vector<T>ist für teuer zu kopierendeTtotal ungeeignet.Nimm nen Pointer-Container, oder nen
vector<shared_ptr<T>>.
-
Sorry, aber ich versteh nur noch Bahnhof...
MfG
Scarabol