Ein Array kreieren, das verschiedene Klassen, die alle von X und Y erben, enthält
-
Das klingt für mich komisch. Vlt ist ein Vector in dem Player und Enemy zusammen vorkommen können, einfach die falsche Datenstruktur.
Wenn du drüber iterieren willst, um gleiche Funktionen aus einer gemeinsamen Basisklasse aufrufen zu können, könntest du auch direkt einen Pointer von der nehmen.
Benötigst du die Vererbung tatsächlich zur Runtime? Sonst ist vielleicht "Compile Time Polymorphism" via Templates die richtige Lösung für dich.
Hier:
https://web.alcf.anl.gov/~zippy/publications/presentations/CompileTimePolymorphism/IBMWatsonTalk.pdf (ich habe nicht alles gelesen, aber die Funktionsweise von Compiletime Polymorphy passt)oder hier:
https://www.c-plusplus.net/forum/topic/325513/compiletime-polymorphism
-
@daniel sagte in Ein Array kreieren, das verschiedene Klassen, die alle von X und Y erben, enthält:
Ok, ich habe versucht da eine Lösung zu finden, und wundere mich über die schöne neue C++ Welt immer mehr. Man erwartet, doch, dass es mit
shared_ptr
möglich sein sollte den altmodischen Code darunter zu ersetzen. Irgend wie funktioniert das nicht. Weiß jemand weshalb der dynamic_pointer_cast nicht funktioniert wie er soll?#include <vector> #include <memory> #include <iostream> class X { public: void virtual methodeX() { std::cout << "methodeX\n"; } }; class Y { public: void virtual methodeY() { std::cout << "methodeY\n"; } }; class Z : virtual public Y {}; class A : virtual public Z, virtual public X {}; class B : virtual public Z, virtual public X {}; using namespace std; int main () { std::vector<shared_ptr<Y>> vy; std::vector<Y*> v; Z z; A a; B b; v.push_back(&z); v.push_back(&a); v.push_back(&b); vy.push_back(make_shared<Y>(Z{})); vy.push_back(make_shared<Y>(A{})); vy.push_back(make_shared<Y>(B{})); for (auto sp: vy) { sp->methodeY(); shared_ptr<X> xp = dynamic_pointer_cast<X>(sp); X* p = xp.get(); cout << "p=" << p << "\n"; if (p) { xp->methodeX(); } } cout << "\n"; for (size_t i = 0, e = v.size(); i != e; i++) { v[i]->methodeY(); X* p = dynamic_cast<X*>(v[i]); if (p) { p->methodeX(); } } }
-
@john-0 aus interesse:
Was geht denn nicht, was gehen sollte?Schon gesehn...
Ich würde die Nullpointer Überprüfung direkt auf dem Shared_ptr machen:if (xp != nullptr) { xp->methodeX(); }
-
@Th69 Ja mit ECS habe ich mich beschäftigt, aber das ist mir derzeit noch zu anspruchsvoll
-
@john-0 Du fügst Ys ein.
vy.push_back(make_shared<Z>()); vy.push_back(make_shared<A>()); vy.push_back(make_shared<B>());
-
@manni66 sagte in Ein Array kreieren, das verschiedene Klassen, die alle von X und Y erben, enthält:
@john-0 Du fügst Ys ein.
Ja, und intuitiv ist es nicht, nicht den Basistyp zu verwenden. Ok, danke für den Hinweis auf das richtige Vorgehen.
-
@john-0 sagte in Ein Array kreieren, das verschiedene Klassen, die alle von X und Y erben, enthält:
Ja, und intuitiv ist es nicht, nicht den Basistyp zu verwenden
Eigentlich schon. Du ersetzt new durch make_shared. Man schreibt nicht
new Y{Z{}}
sondernnew Z
wenn man es einem Y* zuweisen will, weil man es richtig gelernt hat, nicht weil es intuitiv ist..
-
@manni66 sagte in Ein Array kreieren, das verschiedene Klassen, die alle von X und Y erben, enthält:
Eigentlich schon. Du ersetzt new durch make_shared. Man schreibt nicht
new Y{Z{}}
sondernnew Z
wenn man es einem Y* zuweisen will, weil man es richtig gelernt hat, nicht weil es intuitiv ist.Hm, die Rolle von
new Z
übernimmt dochZ{}
(man übergibt ein Objekt und keinen Zeiger mehr auf ein Objekt) und man will je einen SmartPointer von TypY
haben. Mit Boost funktionierte das ganz noch so:boost::shared_ptr<Y> p (new Z);
Deshalb meine Verwirrung. Ok, wieder etwas dazu gelernt, aber vieles vom neuen C++ ist nicht wirklich gut.
-
@john-0 sagte in Ein Array kreieren, das verschiedene Klassen, die alle von X und Y erben, enthält:
Mit Boost funktionierte das ganz noch so:
boost::shared_ptr<Y> p (new Z);Das geht mit std:: genauso, make_shared ist nicht zwingend. Es hat aber z.B. den Vorteil, dass die abgeleiteten Objekte hier korrekt gelöscht werden, obwohl der virtuelle Destruktor in den Basisklassen fehlt.
-
@john-0 sagte in Ein Array kreieren, das verschiedene Klassen, die alle von X und Y erben, enthält:
Deshalb meine Verwirrung. Ok, wieder etwas dazu gelernt, aber vieles vom neuen C++ ist nicht wirklich gut.
Was konkret ist denn nicht gut?
Du musst std::make_shared ja auch mit boost::make_shared vergleichen und std::shared_ptr mit boost::shared_ptr.
Hier ist ein Artikel, warum man das besser mit
make_XXX
stattXXX_ptr<...>(new ...)
machen sollte: https://herbsutter.com/gotw/_102/