Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 |
class Foo { }; class Bar : public Foo { int x; }; Foo* ptr = new Bar(); delete ptr; |
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »anti-freak« (01.04.2015, 10:02)
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Das allein reicht als Beispiel nicht aus. Es ist die Frage danach wie eine per new erzeugte Instanz gelöscht wird. Über einen Pointer auf die Base-Class oder auf einen Pointer auf die abgeleitete Klasse. Ersteres benötigt einen virtual dtor, letzteres nicht. Steht ja aber auch schon in den vorherigen Beiträgen.
In deinem Beispiel wirst Du aber kein Problem bekommen, da int keinen Destruktor rufen muss. Bei einem std::vector wäre es wieder was anderes.
Wenn ich ein polymorphes Konstrukt nutze, sollte ich also den Base Klassen Destructor als virtual deklarieren?
Hmm, kann ich leider so nicht bestätigen. Das stimmt nach meiner Erfahrung nur solange, wie man nur ein konkretes Objekt hat. Hat man aber mehrere oder gar eine Factory (die ein Objekt liefert und gleichzeitig auch die Ownership zurück überträgt), weiß man hinterher eigentlich nicht mehr was ursprünglich mal wie erzeugt wurde. So ein Fall scheint bei Spielen doch sehr üblich zu sein - Entities (NPCs/Monster/etc), AI-Typen, Ausrüstungen, etc.Den Fall, dass ich polymorphes delete benötige, habe ich relativ selten, da der Besitzer eines Objektes meistens den konkreten Typ kennt, auch wenn das Objekt an anderen Stellen polymorph verwendet wird...
Dieser Beitrag wurde bereits 16 mal editiert, zuletzt von »dot« (01.04.2015, 10:30)
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 |
// dtor is virtual, deleten möglich FooException* foo_ptr = new FooException (1, "1 error"); FooBaseException* foo_base_ptr = dynamic_cast<FooException*>(foo_ptr); // or boost::..._downcast delete foo_base_ptr; // dtor ist protected non-virtual, deleten nicht möglich //Foo* foo_ptr = new FooException (1, "1 error"); //Master* master_ptr = static_cast<Master*>(foo_ptr); //delete master_ptr; |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
// nicht abstract, nix virtuales class Master { protected: // attrs // wird von anderen Klasse geerbt, dtor deklarieren ~Master() = default; public: Master(); // Master(...); void dostuff(); }; class Foo : public Master { public: Foo(); // kein dtor override notwendig }; // abstract class BasePrinter { // muss virtual sein bei abstract //protected: //~BasePrinter(); // theoretisch könnte man doch alles protected machen ? public: BasePrinter(); // warning: 'BasePrinter' has no out-of-line virtual method // definitions; its vtable will be emitted in every translation unit // [-Wweak-vtables] // in .cpp auslagern virtual ~BasePrinter(); virtual void print(std::ostream& out) = 0; }; class IntPrinter : public BasePrinter { public: IntPrinter(); // kein dtor override notwendig ? // warning: 'IntWriter' has virtual functions but non-virtual destructor [-Wnon-virtual-dtor] // virtual dtor in public, nicht non-virtual dtor in protected virtual ~IntPrinter() = default; // override virtual methode void print(std::ostream& out) override; }; // std::runtime_error hat virtual dtor class FooBaseException : public std::runtime_error { protected: // info error stuff int _errc; public: FooBaseException(int errc, std::string msg) : std::runtime_error(msg) , _errc(errc) {} // warning: 'FooBaseException' has no out-of-line virtual method // definitions; its vtable will be emitted in every translation unit // [-Wweak-vtables] // dtor auslagern nach .cpp // virtual ~FooBaseException() = default; virtual ~FooBaseException(); int getErrc() const { return this->_errc; } }; // warning: 'FooException' has no out-of-line virtual method // definitions; its vtable will be emitted in every translation unit // [-Wweak-vtables] class FooException : public FooBaseException { public: FooException(int errc, std::string msg) : FooBaseException(errc, msg) {} // warning: 'FooBaseException' has no out-of-line virtual method // definitions; its vtable will be emitted in every translation unit // [-Wweak-vtables] // dtor auslagern nach .cpp ~FooException() override; // other ctors, methodes }; |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
warning: definition of implicit copy constructor for 'FooException' is deprecated because it has a user-declared destructor [-Wdeprecated] FooException::~FooException(){ ^ note: implicit copy constructor for 'FooException' first required here FooException new_foo_exc = foo_exc; // or throw foo_exc; ^ warning: definition of implicit copy constructor for 'FooBaseException' is deprecated because it has a user-declared destructor [-Wdeprecated] FooBaseException::~FooBaseException(){ ^ note: implicit copy constructor for 'FooBaseException' first required here class FooException : public FooBaseException { ^ |
Werbeanzeige