Zugriff auf Methoden abgeleiteter Klassen die allerdings nicht in der Basisklasse definiert sind mit Basisklassenzeiger



  • fluxy schrieb:

    Na schön... Also der Anwendung Zugriff auf alle Interfaces zu geben kann ich eventuell noch mit leben...

    du musst es sogar erlauben, da du die klasse sonst nicht verwenden könntest

    Allerdings sehe ich das nur als Verschiebung des Problems. Denn, was mache ich, wenn jetzt eine Pluginklasse, die Beispielsweise von XComGuiBase abgeleitet ist, eine Methode definiert, die in dem Interface nicht vorhanden ist. Dann komm ich auch mit einem Zeiger auf XComGuiBase nicht mehr weiter, sondern muss dann auf die spezielle Klasse casten.

    wie wärs mit nem speziellen interface für die jeweiligen klassen?

    Jetzt mal was spricht dagegeben: Die Anwendung darf von den Klassen nix wissen. Wenn Sie davon wissen, ist die Kapselung komplett im Eimer und der Vorteil der Plugins verschwindet damit. Der Vorteil ist ja grade, dass die Anwendung von den Klassen nix wissen braucht.

    erklär mir mal, wie du eine klasse auch nur irgendwie benutzen willst, wenn du der anwendung nichmal erlauben willst, das interface zu kennen.

    der sinn solch eines plugin systems ist, eine reihe spezieller interfaces zu bieten, nach denen sich die plugins zu richten haben, nicht das system welches die plugins verarbeiten muss.
    du hast normalerweise nur 2 möglichkeiten: variables front end, oder variables back end, beides zusammen kann nicht klappen.

    dh: du lädst ein GUI plugin.
    die klassen kannst du über interfaces+factory classes benutzen. nun muss sich das plugin danach richten,wie du die interfaces aufgebaut hast, denn nur so ist eine allgemeine benutzbarkeit möglich, und nur so hat man überhaupt die möglichkeit, 2 plugins austauschen zu können.

    wenn die plugins nicht garantieren können, dass sie über deine standardinterfaces problemlos zu benutzen sind, dann ist es ein fehler des plugins.

    aber eins ist klar, die standardinterfaces müssen deiner anwendung und dem plugin bekannt sein, denn sie dienen als verbindung, ohne diese verbindungen bist du absolut aufgeschmissen.

    Und was den Cast angeht: ich weiss jetzt nicht obs der richtige Cast ist, aber in dem Fall kann ich auch direkt nen dynamic_cast machen. Ob ich jetzt meinen Zielpointer auf void** caste oder direkt nen Cast auf die Zielklasse angebe ist doch eigentlich egal. Im Prinzip finde ich die zweite Möglichkeit in dem Fall sogar noch besser, weil dort 1 Schritt weniger ausgeführt werden muss.

    kommt ganz auf den zweck an, manchmal reicht ein simpler dynamic_cast nicht,vorallem wenn sich die objekte auf die das interface zeigen soll danach richten, mit welchem interface sie ausgeführt werden,mit einem queryInterface ist man auf jedenfall auf der sicheren seite,da da der ersteller des plugins entscheiden kann, was passieren wird, bei einem dynamic cast ist dies nicht möglich.

    @ssm und bei jeder code erweiterung muss man dann in 2 klassen veränderungen tätigen?



  • hmmm also das von ssm.... cool..... aber Ohne kommentar verstehe ichs wohl nicht.

    Kannst du es vielleicht mal erläutern?!



  • otze schrieb:

    @ssm und bei jeder code erweiterung muss man dann in 2 klassen veränderungen tätigen?

    ja, aber bu brauchst in diesem Fall keinen dynamic_cast zu machen. es ist dir zu entscheiden, was besser ist :p
    "double dispatching" soll aber schneller arbeiten



  • Das Interface habe ich. Aber um es mal ganz klas auszudrücken ein anderer Fall. Angenommen wir haben nur 1 Interface für das Plugin

    class Basis 
    {
    public:
    virtual void test (void) = 0;
    };
    

    und die Pluginklasse definiert eine andere methode die nicht im Interface sein darf:

    class Abgeleitet
    {
    public:
    virtual void irgendwas (void);
    };
    

    und ich habe jetzt meinen Baisklassenzeiger:

    Basis* test = new Abgeleitet ();
    

    wie bekomme ich jetzt ohne von der Klasse Abgeleitet zu wissen Zugriff auf die Mentode irgendwas???



  • das system is einfach:
    du übergibst registerplugin einen nach XComBase* konvertierbaren pointer.
    innerhalb der funktion wird dann versucht die richtige version von accept aufzurufen,accept macht dann irgendetwas mit dem pointer,je nachdem wie die implementierung ist

    @ssm jo das is richtig, ich wollte ja auch nie nen dynamic cast verwenden :p



  • fluxy schrieb:

    hmmm also das von ssm.... cool..... aber Ohne kommentar verstehe ichs wohl nicht.

    Kannst du es vielleicht mal erläutern?!

    es ist mir ein bischen schwierig auf Deutsch zu erläutern, weil ich noch nich besonders fit in Deutsch bin. du kannst über pattern Visitor z.B. im Internent lesen:

    http://kilana.unibe.ch:9090/ese2003gruppen-smallwikis/southsidecrewssc/patternserklrt/visitor/

    wenn du weiter die Fragen hast, kann ich versuchen es zu erklähren



  • otze schrieb:

    das system is einfach:
    du übergibst registerplugin einen nach XComBase* konvertierbaren pointer.
    innerhalb der funktion wird dann versucht die richtige version von accept aufzurufen,accept macht dann irgendetwas mit dem pointer,je nachdem wie die implementierung ist

    @ssm jo das is richtig, ich wollte ja auch nie nen dynamic cast verwenden :p

    genau, das hab ich vergessen.
    es gibt noch bessere Lösung, von Andrey Aleksandrevsku. 🕶



  • @fluxy

    Der Sinn dieser Kapselung ist, dass Du keinen! Zugriff auf die Methode irgendwas bekommst. Um die Methode irgendwas aufzurufen kann Dein Plugin aber die Methode test (oder irgendeine andere passende virtuelle Methode des Interface) überschreiben und von dort aus selbst die Methode irgendwas aufrufen.

    Vielleicht ist es so verständlicher ?

    DJohn

    EDIT: zu langsam. Das bezieht sich auf das letzte Beispiel von fluxy



  • von wem?!

    wie wären denn die besseren lösungen?

    ach und deutsch muss net sein... ich bin auch der englischen Sprache mächtig.



  • ssm schrieb:

    otze schrieb:

    das system is einfach:
    du übergibst registerplugin einen nach XComBase* konvertierbaren pointer.
    innerhalb der funktion wird dann versucht die richtige version von accept aufzurufen,accept macht dann irgendetwas mit dem pointer,je nachdem wie die implementierung ist

    @ssm jo das is richtig, ich wollte ja auch nie nen dynamic cast verwenden :p

    genau, das hab ich vergessen.
    es gibt noch bessere Lösung, von Andrey Aleksandrevsku. 🕶

    jo, sein buch lliegt grad neben mir, hats zb mit ner typliste geschafft, was ein teufelskerl 🕶



  • fluxy schrieb:

    von wem?!

    von Andrei Alexandrescu, http://www.moderncppdesign.com/

    fluxy schrieb:

    wie wären denn die besseren lösungen?

    http://sourceforge.net/projects/loki-lib/
    die sind aber sehr kompleciert

    fluxy schrieb:

    ach und deutsch muss net sein... ich bin auch der englischen Sprache mächtig.

    ich kann ohne Probleme English, Deutsch, Russisch verstehen, aber schreiben ...
    meine Muttersprache ist ukrainish 😞



  • otze schrieb:

    jo, sein buch lliegt grad neben mir, hats zb mit ner typliste geschafft, was ein teufelskerl 🕶

    ja, genau, es gibt keine andere Benennung 😃



  • hmmm,

    also wie viel besser sind die denn als deine Lösung. Also die Lösung mit dieser Factory habe ich noch nicht so ganz verstanden. Deshalb eine Frage:

    Wenn ich die Factory benutzte dann brauche ich keinen Cast mehr auf meine anderen Klassen, also meine Anwendung braucht die anderen Klassen auf keinste weise mehr zu kennen?!?

    Bitte um ne klare Antwort.



  • das interface muss immernoch gekannt werden,das is auch kein unterschied zu dynamic_cast oder dem was ich vorgeschlagen hab🙄

    und die andre lösung von Andrei Alexandrescu ist vom niveau her für uns hier unerreichbar. 🙂



  • otze schrieb:

    das interface muss immernoch gekannt werden,das is auch kein unterschied zu dynamic_cast oder dem was ich vorgeschlagen hab🙄

    Geschwindigkeit? RTTI?

    otze schrieb:

    und die andre lösung von Andrei Alexandrescu ist vom niveau her für uns hier unerreichbar. 🙂

    man braucht IMHO einfach viel Zeit, um sie zu verstehen. Aber die Idee ist SUPER 🕶 🕶 🕶



  • das interface oder die klasse? was ist wenn ich nur ein interface habe und habe eine Methode in der abgeleiteten Klasse die das interface nicht hat?



  • fluxy schrieb:

    hmmm,

    also wie viel besser sind die denn als deine Lösung. Also die Lösung mit dieser Factory habe ich noch nicht so ganz verstanden. Deshalb eine Frage:

    Wenn ich die Factory benutzte dann brauche ich keinen Cast mehr auf meine anderen Klassen, also meine Anwendung braucht die anderen Klassen auf keinste weise mehr zu kennen?!?

    Bitte um ne klare Antwort.

    wie otze schrieb, muss interface gekannt werden. Wenn ich richtig verstand, du hast doch diese Information.



  • Geschwindigkeit? RTTI?

    normalerweise richtig, in dem kontext aber nicht relevant

    ansonsten hat ssm uneingeschränkt recht 🙂

    @fluxy wenn die abgeleitete klasse eine methode hat, die kein dir bekanntes interface ansprechen kann, dann wirst du wohl auf diese methode verzichten müssen.

    in einem plugin system, welches sich aus verschiedenen dlls läd könntest du eh nichts mit der "neuen" methode anfangen, da du sie nicht kennen KANNST.



  • fluxy schrieb:

    das interface oder die klasse? was ist wenn ich nur ein interface habe und habe eine Methode in der abgeleiteten Klasse die das interface nicht hat?

    du sollst diese Methode im interface einfügen, oder du kannst ein interface in daine Klasse einfügen, die Client nich siet:

    [cpp]struct IHidden;
    struct IPluggin;

    struct IVisitor
    {
    virtual void accept(IHidden *hidden) = 0;
    virtual void accept(IPluggin *pluggin) = 0;
    };

    struct IPluggin
    {
    virtual void init() = 0;
    virtual void abort() = 0;
    virtual void stop() = 0;
    virtual accept(IVisitor *visitor);
    };

    struct IHidden
    {
    virtual void magic() = 0;
    };

    template<typename>
    class PlugginImpl
    {
    };

    class MyPluggin1 : public PlugginImpl<MyPluggin1>, IHidden
    {
    virtual void magic()
    {
    std::cout << "make magic\n";
    }

    virtual apply(IVisitor *visitor)
    {
    visitor->accept(static_cast<IHidden>(this));
    }
    };[/cpp]



  • Welchen Ansatz verfolgt denn dieser Typ da?


Anmelden zum Antworten