Container für verschiedene Pointer



  • hallo,

    ich habe mehrere verschidene Pounter, z.B.

    IBase *p1, *p2;
    IClass *p3, *p5, *p6;
    IAnother *p7,...
    .....

    ich muss diese pointer verwalten, das heisst in einen Container abspeichern,
    gibts einen Container dafür ?
    am liebsten wäre mir so was wie std::map(pointer, std::string),
    geht aber nicht, da alle diese pointer verschiedene Typen haben, die erst bei laufzeit bekannt sind,

    danke



  • Wie wäre es mit void* statt einem bestimmten Zeigertyp?



  • ginge natürlich auch, aber ist void* nicht schlecht ? habe gehört, es sollte vermieden werden bzw man hat beim design mist gebaut,
    (mich würde dann trotzdem interessieren anhang von einem beispiel wie du das machen würdest mit void*)

    aber problem ist.... ich muss irgnedwie dann zeiger aus dem container rausholen, ohne die zu casten dann auf die zugreifen, bei void* ginge das nicht....



  • Du kannst in einem Container nicht einfach so verschiedene Typen unterbringen welche nichts gemeinsam haben.

    Vielleicht könnte dir aber boost::variant dabei helfen.



  • Alle brauchen eine gemeinsame Basisklasse. Dann gehts.



  • Alleine nützt dir das trotzdem nix. Denn wenn du die Zeiger wieder brauchst, weisst du nicht, welche Klasse sich dahinter verbirgt, da du ja nur einen Zeiger auf die Instanz der Basisklasse hast. Sicherlich, du kannst alle Möglichkeiten mit dynamic_cast durchgehen. Nur wirklich toll ist das nicht.
    Eine Möglichkeit die ich sehe, und um den Gedanken aufzunehmen, wäre eine Basisklasse, die die benötigte Funktionalität über virtuelle Funktionen bereitstellt.



  • ja das meinte ich doch mit den virtuellen funktionen. 🤡



  • WeiserCoder schrieb:

    da alle diese pointer verschiedene Typen haben, die erst bei laufzeit bekannt sind,

    😕
    Wie kriegt man das denn in C++ hin? Da kennt man doch den Typ seiner Pointer zu jedem Zeitpunkt genau.



  • leider haben alle klassen KEINE gemeinsame basisklasse....

    also ich versuche das problem noch genauer zu schildern:

    es gibt mehrere DLL dateien in bestimmten verzeichnis (plugins),
    alle die DLL's sollen automatisch dynamisch geladen werden aus bestimmten verzeichnis, und jede von diesen DLL exportiert jeweils eine methode

    "xxx* GetPointer()"
    

    wobei xxx* bei jeder DLL anders ist, z.b. IClassOne*, IAnotherClass* usw... die alle haben keine gemeinsame basisklasse....
    diese zeiger sind alles zeiger auf pure abstract interfaces,

    ich will folgendes realisieren....
    dass bei diesem vorgang alle DLL's automatisch geladen werden und jeweils diese eine methode soll aufgerufen werden, und der zurückgelieferter zeiger soll gespeichert werden, in der art wie

    Pseudocode:
    
    container  c;
    while(lade dlls)
    {
        c.push_back(verschidene zeiger, name der dll);
    }
    

    wobei das problem ist, dass zeiger verschiden sind und keine gemeinsame klasse haben, deswegen kenne ich keinen passenden container dafür

    im code würde ich gerne dann so zugreifen auf diesen container...

    Pseudocode:
    
    IClassOne* p = c["einplugin.dll"];
    p->tu irgendwas;
    

    wobei das ohne cast geschehen soll, das ist das problem, also es müssen alle zeiger schon gecastet im container drin stehen,

    PS: oder gibts da eine art design pattern für das ganze ? bzw kennt jemand eine bessere methode so was zu realisieren ? zwecks: pluginmanager
    gruss



  • Ja da gibts nen Trick: man schafft nen einheitliches Interface für das Pluginsystem



  • @WeiserCoder
    Ein Plugin System funktioniert aber anders. Wenn du Plugins hast, die Instanzen verschiedener Klassen zurückgeben, dann hast du auch verschiedene Plugins. Was ja durchaus möglich ist. Ich benutze zB den Total Commander und da gibt es Lister-, Packer- und Filesystem- Pluigns. Du musst dann aber jeden Typ von Plugin auch separat behandeln. Du nimmst dann einfach einen Container der alle IClassOne* aufnimmt, einen der alle IAnotherClass* aufnimmt usw. Und diese behandelst du dann auch separat.
    Wenn es allerdings Plugins des selben Typs sind, dann musst du es wie SirLant sagte machen. Dh GetPointer() liefert immer zB IClass* zurück.



  • leider kann ich das nicht machen....

    grund:

    es gibt einen PluginManager, der ist schon fest integriert im code und vorkompiliert(dll), also kommt es schlecht in frage, dass es ein neues plugin entwickelt wird mit einem neuen interface, dass ich dann PluginManager erweitern soll, z.b. neue methode rein INeuerPlugin* GetNeuerPlugin();
    das kann ich aber nicht machen, wie gesagt, pluginmanager ist schon vorkompiliert,

    gibts noch evtl andere idee oder möglichkeit das ganze zu lösen ?



  • Damit erweist sich dieser Plugin-Manager aber definitiv als Fehlkonstruktion.

    mfg JJ



  • Sorry WeiserCoder sowas kann nicht funktionieren.



  • Nen Pluginmanager der mit solchen Plugins arbeitet muss aber alle Plugins im voraus kennen, daher kannst du dann ja auch einfach alles hart kodieren.



  • wie würdet ihr denn euren Pluginmanager aufbauen ?

    zweck:
    eine grafikengine, wobei hauptkern als dll da ist, und wenn was neues dazu kommt (plugins) auch als dll geladen werden kann, damit man das auch nutzen kann...

    problem:
    die plugins, die bei entwicklung der engine fertiggestellt werden, kann man problemlos dann bei dem pluginmanager aufrufen mit IVorhanderInterface GetDiesenInterface()...
    bei plugins, die später dazu kommen (wenn engine zum download bereit steht), kann man das nicht machen, da neue Interfacetypen dazu kommen, da pluginmanager schon in einer dll drin ist, kann man solche methoden nicht mehr dazu einfügen wie INeuerInterface
    GetNeuerInterface();...

    gibts da eine andere lösung pluginsystem zu realsieren ? oder lösung für dieses problem ?



  • mach es anders;
    anstatt direkt den pointer zu speichern, kannst du den pointer doch selber wrappen

    struct PointerInfo
    {
       enum PointerType { PT_IBASE, PT_ICLASS, PT_IANOTHER };
       PointerType pointer_type;
       void *pointer;
    };
    

    dann hast du alles was du brauchst und kannst deine pointer einfach verwalten



  • Wie willst du denn ein Plugin benutzen wenn du nicht sein Interface kennst? Dann kannst du doch gar keine Funktionen davon aufrufen. Ich raff das nicht.



  • esskar schrieb:

    mach es anders;
    anstatt direkt den pointer zu speichern, kannst du den pointer doch selber wrappen

    struct PointerInfo
    {
       enum PointerType { PT_IBASE, PT_ICLASS, PT_IANOTHER };
       PointerType pointer_type;
       void *pointer;
    };
    

    dann hast du alles was du brauchst und kannst deine pointer einfach verwalten

    ich verstehe nicht ganz, wie du dann den void pointer casten willst....
    in enum speicherst du ja dann nur die ID's keine pointertypen,
    und zweitens, wie soll dann so in pseudocode so ein pluginmanager aussehen ?
    danke schon mal im vorraus



  • nixraff schrieb:

    Wie willst du denn ein Plugin benutzen wenn du nicht sein Interface kennst? Dann kannst du doch gar keine Funktionen davon aufrufen. Ich raff das nicht.

    doch, interface kenne ich ja dann schon, weil es includet wird, nur das problem ist dabei, pluginmanager hat keine funktion vorraus deklariert genau auf diesen pointertyp zuzugreifen, falls es ein neuer plugin ist, mit neuem interface, da der pluginmanager in einer dll liegt und nicht mehr zu ändern wäre


Anmelden zum Antworten