Zeiger kopieren
-
Hallo. Ich habe schon kurz gegooglet, aber aufgrund der Mangelnden Zeit habe ich keine Zeit für ausführliche Recherchen.
Ich habe in einer
mapZeiger auf auf meine Basisklasse.Deklaration:
std::map<Block_ID, Block*> BLOCKS;An einer anderen Stelle weiße ich
Block*eine abgeleitete KlasseBlock_Air*zu.BLOCKS[Block_ID(0)] = new Block_Air();Und während der Laufzeit möchte ich, dass der Zeiger kopiert wird und dann in einem anderen zeiger gespeichert wird.
Block* block = BLOCKS[Block_ID(0)];Wenn ich das mache, dann hat
blockden gleichen Zeiger wieBLOCKS[Block_ID(0)]. Wie kann ich machen, dass inblockeine Kopie vonBLOCKS[Block_ID(0)]gespeichert wird, also dass ein neues Objekt von z.B.Block_Airerzeugt wird???
-
In der Block KLasse:
class Block { public: virtual Block* clone() = 0; };In BlockAir und allen anderen Klassen, die von Block abgeleitet sind:
class BlockAir: public Block { public: virtual Block* clone() { return new BlockAir(*this); } };Edit:
Alternative: (Ich bin nicht ganz sicher ob das erlaubt ist)class BaseBlock { //Zeiger auf diese Klasse in der Map speichern public: // Gemeinsames Interface aller Blöcke // ... virtual BaseBlock* clone() const = 0; // Virtueller Destruktor private: // Konstruktor hier template <class> friend Cloneable; }; template <class Child> class Block { // Alle Blocktypen erben von dieser Klasse. Sie müssen nichts // anderes machen. public: virtual BaseBlock* clone() const { return new Child(*static_cast<Child*>(this)); } // Mit c++11 // virtual BaseBlock* clone() const final override { return new Child(*static_cast<Child*>(this) ); } protected: Block() {} // Oder mit C++11: Block() = default. virtual ~Block() {} // Oder mit C++11: virtual ~Block() = default; };Benutzung (gilt für beider Varianten) :
Block * ptr = new BlockAir(); // Für Variante 2 : BaseBlock * ptr Block * ptr2 = ptr -> clone();
-
@pyhax: Der Returntyp in der abgeleiteten Klasse braucht nicht identisch zu sein mit dem in der Basisklasse, er darf auch spezialisierter sein. Du kannst also ganz korrekt einen Block* zurückgeben. Dies erspart dir möglicherweise ein paar dynamic_casts o.Ä. falls du mal direkt einen Block* kopieren möchtest. Das Stichwort dazu ist "Covariant return types".
-
Die erste Variante von phyax funktioniert.
Jetzt habe ich ein anderes Problem:
Ich habe in meienr
World-Klasse ein Array:Chunk chunks[64][64][16];Chunkhat aber nur einen Konstruktor (und das mit gutem Grund!)Chunk(World* welt);Ich würde das gerne so lösen:
class World { private: Chunk chunks[64][64][16](this); //Der ganze Rest };Das geht aber nicht!
Wie könnte ich das lösen?
(Ohne einen neuen Konstruktor!!)
-
SeppJ schrieb:
@pyhax: Der Returntyp in der abgeleiteten Klasse braucht nicht identisch zu sein mit dem in der Basisklasse, er darf auch spezialisierter sein. Du kannst also ganz korrekt einen Block* zurückgeben. Dies erspart dir möglicherweise ein paar dynamic_casts o.Ä. falls du mal direkt einen Block* kopieren möchtest. Das Stichwort dazu ist "Covariant return types".
Block ist doch ein Template, das heißt ich müsste doch dann sowieso den Typ des Objektes kennen, und dann kann ich doch gleich einen Static_cast verwenden?
-
Wie ja schon gesagt, deine erster Variante funktioniert.
Könntet ihr euch vieleicht auf das andere (neue) Problem konzentrieren!
Oder soll ich einen neuen Thred aufmachen???
-
Nein. "Das geht aber nicht." ist keine Fehlerbeschreibung.
-
Es geht nicht.
Das heißt, in der Form, in der ich es machen will, lässt mich der Kompiler das nicht machen.
e:\eigene dateien\visual studio 2010\projects\block forge\map\world.h(12): error C2059: Syntaxfehler: 'this' e:\eigene dateien\visual studio 2010\projects\block forge\map\world.h(12): error C2092: 'chunks' Arrayelementtyp kann keine Funktion sein World.cpp e:\eigene dateien\visual studio 2010\projects\block forge\map\world.h(12): error C2059: Syntaxfehler: 'this' e:\eigene dateien\visual studio 2010\projects\block forge\map\world.h(12): error C2092: 'chunks' Arrayelementtyp kann keine Funktion seinSyntaxfehler! => Geht so nicht!
P.S.: Ich hab im (letzten) Code(-auschnitt) vergessen die Klammern nach
...[16]zu setzten. Jetzt stimmts!
-
Ich denke da musst du einen Defaultknstruktor hinzufügen. Warum willst du das nbedingt veremeiden?
-
Weil sonst aus ungeklärten Gründen die Objekte nicht erzeugt werden!
Od das obwohl ich nachträglich nochmals den gewünschten Konstruktor aufrufe!