Liste mit void*
-
Ollow_AM schrieb:
struct MyBspStruct { void* MyObject; MyObjectType MyType; // enum für den Type };Dies ist nötig damit ich auch entsprechende wieder zurückcasten kann.
Glaube ich dir nicht so ganz. Das geht möglicherweise auch besser vom Design her.
Ollow_AM schrieb:
Wirkliche Gemeinsamkeiten der Objecte gibt es nicht. So das wenn ich eine Basisklasse schaffen würde, diese eigentlich so gut wie keine virtuell überschriebene Funktionen enthalten würde. Das bedeutet das ich mir auch den Type merken müsste. Um zurück zu casten.
Nur mal so am Rande: Wem "gehören" denn die Objekte? Also, in welchem Speicher stehen sie? Falls im Freispeicher: Wer gibt sie wieder frei?
Ollow_AM schrieb:
Gibt es evtl. noch eine weiter Lösung...??
Bestimmt.
Da du dir den Typ eh merken willst, kannst du dir im Notfall auch einen "anyptr" bauen, der sich das für dich schon richtig merkt. So könntest wenigstens Typfehler reduzieren.
Ollow_AM schrieb:
Bzw. was ist die sinnvollere und im Programm schnellere Variante und warum??
Wie verhält sich das ganze wenn MyObject im Orginal kein Zeiger ist sondern eine Variable. Ist der cast zu 'void*' und von 'void*' auch dann noch sicher??Zu wenig Information du verraten hast. Vielleicht ist boost::any doch das, was du willst, wenn du es nicht mal auf Zeiger beschränken kannst.
Cheers!
k.k.
-
Ollow_AM schrieb:
Wie bereits erwähnt ist es das Ziel die Objecte unabhängig vom Typen in einer Liste zusammenzuführen, welche anschließend nacheinander abgearbeitet werden.
Sry, aber das klingt stark nach kaputtem Design. Wie genau hast du vor, Objekte, die absolut nichts miteinander zu tun haben, an einer gemeinsamen Stelle "abzuarbeiten" und vor allem wieso?
-
Hallo,
ich schreib mal kurz für Ollow_AM, wir sind im gleichen Team.
Stellt euch das folgt vor.
Ich habe eine Liste an Reifen, die ich bewegen kann. Z.B. Reifen->Drehen();In der gleichen Liste habe ich z.B. auch Autos, die 4 Reifen beinhalten, aber diese nicht erben können. Auto->Alle4ReifenDrehen();
In der gleichen Liste habe ich aber auch Motorräder mit 2 Reifen, die sich ebenfalls vorwärts bewegen können. Motorrad->Alle2ReifenDrehen();
Also schaut meine Liste ähnlich dem aus:
namespace Afgrammt { enum WasReifenHat { IsReifen = 0, IsAuto, IsMotorrad }; struct InListe { void* MitReifen; Afgrammt::WasReifenHat WasIstEs; }; }; typedef std::list<InListe> Reifenliste;Nun kann ich alles was Reifen hat in die Liste legen und je nachdem was es für ein Typ ist, kann den Ursprungstype zurück casten und dann die jeweilige Funktion zum Reifen drehen aufrufen.
Natürlich wird jetzt jeder sagen => schlechtes Design, warum nicht eine abstracte Class reinerben, die eine Funktion "virtual void DreheAlleReifen() = 0;" hat und mit Zeiger darauf arbeiten.
Die Antwort ist einfach: Weil die Klassen, die wir hier ablegen leider Gottes aus DLLs kommen, die von mehreren anderen Programmierern geschrieben werden und wir keine Möglichkeit haben auf die h-Dateien und Vererbungen Einfluss zu nehmen.Daher dieser Ansatz.
Also kurzum: Jede Klasse hat eine andere Funktion, die ich Anhand des Klassen-Typ aufrufen muss und ich habe keine Möglichkeit am Design der enthaltenen Klassen etwas zu ändern.
-
Und warum könnt ihr nicht einfach eine Liste für alle Reifen, eine Liste für alle Autos und eine Liste für alle Motorräder haben?
One list to rule them all, one list to find them, one list to bring them all and in darkness bind them...
-
Macht doch einfach Adapter um die fremden Klassen drumherum. Dann müsst ihr euch mit den verschiedenen Interfaces nicht an jeder Stelle in eurem Code erneut rumschlagen, sondern habt das einmal schön gebündelt und könnt innerhalb eurer Anwendung sauber programmieren.

-
dot schrieb:
Und warum könnt ihr nicht einfach eine Liste für alle Reifen, eine Liste für alle Autos und eine Liste für alle Motorräder haben?
One list to rule them all, one list to find them, one list to bring them all and in the darkness bind them...
Weil die Liste von verschieden Stellen aus gefüllt wird und wir die Liste von oben nach unten (per Events und immer nur 1 Eintrag pro Eventloop) abarbeiten.
-
Dann steckt die drei Listen in eine Klasse?
-
Dobi schrieb:
Macht doch einfach Adapter um die fremden Klassen drumherum. Dann müsst ihr euch mit den verschiedenen Interfaces nicht an jeder Stelle in eurem Code erneut rumschlagen, sondern habt das einmal schön gebündelt und könnt innerhalb eurer Anwendung sauber programmieren.

Ist mein struct nicht eigentlich bereits "der" Adapter?
Also wenn ich den struct in class umschreibe und die Aufrufe innerhalb abwickle?
So gemeint?
-
dot schrieb:
Dann steckt die drei Listen in eine Klasse?
Aber ich bräuchte noch eine Liste, die mir sagt, wer dran ist...
struct WerIstDran { template<class ListTyp> std::list<ListTyp> WelcheListe; size_t Position; }; std::list<WerIstDran> MeineReifenZudrehen;Ist glaube ich auch nicht dienlich?!?
-
-
stefanjann schrieb:
Dobi schrieb:
Macht doch einfach Adapter um die fremden Klassen drumherum. Dann müsst ihr euch mit den verschiedenen Interfaces nicht an jeder Stelle in eurem Code erneut rumschlagen, sondern habt das einmal schön gebündelt und könnt innerhalb eurer Anwendung sauber programmieren.

Ist mein struct nicht eigentlich bereits "der" Adapter?
Also wenn ich den struct in class umschreibe und die Aufrufe innerhalb abwickle?
So gemeint?Ne, ich meinte eher sowas:
#include <list> #include <iostream> #include <memory> #include <algorithm> class FremdesAuto { public: void Alle4ReifenDrehen() { std::cout << "Auto" << std::endl; } }; class FremdesMotorrad { public: void Alle2ReifenDrehen() { std::cout << "Motorrad" << std::endl; } }; class Fahrzeug { public: virtual ~Fahrzeug() {} virtual void DreheAlleReifen() = 0; }; class MeinAuto : public Fahrzeug { virtual void DreheAlleReifen() override { fremdesAuto_.Alle4ReifenDrehen(); }; private: FremdesAuto fremdesAuto_; }; class MeinMotorrad : public Fahrzeug { virtual void DreheAlleReifen() override { fremdesMotorrad_.Alle2ReifenDrehen(); }; private: FremdesMotorrad fremdesMotorrad_; }; int main() { typedef std::shared_ptr<Fahrzeug> FahrzeugPtr; std::list<FahrzeugPtr> fahrzeuge; fahrzeuge.push_back(std::make_shared<MeinAuto>()); fahrzeuge.push_back(std::make_shared<MeinMotorrad>()); std::for_each(std::begin(fahrzeuge), std::end(fahrzeuge), [](FahrzeugPtr ptr) { ptr->DreheAlleReifen(); }); }
-
@all: Danke.
Ich glaube der Ansatz von Dobi bringt und am weitesten.
Aber ich werde mich noch weiter mit dem Thema auseinandersetzen (müssen).Ich sehe die Frage als Beantwortet an.