Pimpl-Idiom



  • Hallo,

    ich beschäftige mich gerne mit objekt-orientierten Konzepten und bin dabei auf
    das pimpl-idiom gestoßen. Ich muß sagen, ein interessantes Konzept, allerdings
    sehe ich nicht den wirklichen Hintergrund des Konzeptes.
    Okay, wenn ich in einem Team arbeite und meine Mitarbeiter meine Klassen
    verwenden, verschone ich diese von meiner Implemtierung. Auch müssen diese
    ihren code nicht ändern bzw. neu übersetzen, wenn ich an der Implementierung
    ändere.
    Super Sache! Aber schaffe ich mir nicht einen gewissen Overhead durch
    zusätzliche Heap-Allokationen bei meinen Projekten, für die ich eigenständig
    verantwortlich bin??? Schieß ich da nicht etwas mit Kanonen auf Spatzen,
    wenn ich mir bei einer Klasse überlege ob ich dieses Konzept zum Einsatz
    bringe? Ist das pimpl-idiom nur für Biblitheken sinnvoll?

    Mich würden sinnvolle Aspekte interessieren, warum ich meine Klasse nach
    diesem Konzept designen sollte.



  • Frank++ schrieb:

    Okay, wenn ich in einem Team arbeite und meine Mitarbeiter meine Klassen verwenden, verschone ich diese von meiner Implemtierung. Auch müssen diese ihren code nicht ändern bzw. neu übersetzen, wenn ich an der Implementierung ändere.
    Super Sache!

    ok, super sache.

    Aber schaffe ich mir nicht einen gewissen Overhead durch
    zusätzliche Heap-Allokationen bei meinen Projekten, für die ich eigenständig
    verantwortlich bin??? Schieß ich da nicht etwas mit Kanonen auf Spatzen,
    wenn ich mir bei einer Klasse überlege ob ich dieses Konzept zum Einsatz
    bringe? Ist das pimpl-idiom nur für Biblitheken sinnvoll?

    ok, ein wenig overhead.

    man zahlt manchmal gerne ein wenig overhead für ne super sache.
    das erste c++-buch, das ich las, hat empfohlen, pimpl ganz oft zu nehmen, eigentlich immer, wenn man damit übersetzungszeit sparen kann. allerdings stets mit dem hintergedanken, daß pimpl nur für die entwicklungszeit da ist und später weider gekickt wird, um ein wenig mehr performance im ferigen programm zu haben.
    eigentlich versteckt pimpl ja nur die impl, ändert aber sonst nix am design. also müßte man doch immer sich aussuchen können, ob man gerade mal pimpl macht oder nicht.



  • PIMPL hat in C++ mehrere Berechtigungen. Es geht imemr darum, Interface von Implementation zu trennen, aus verschiedenen Gründen:

    a) Einzige Möglichkeit zur Vermeidung rekursiver Header-Includes (A muß B kennen, und B muß A kennen).

    b) Aus Design-Gründen
    "Gehört sich halt so". Würde ich aber als alleinigen Grund nicht so verbissen sehen

    c) Verkleinern des nach außen sichtbaren Interfaces
    mit PIMPL kann man in einigen Fällen ganz effektiv das nach außen sichtbare Interface von ein paar Klassen bereinigen. Was schon deshalb sinnvoll ist, weil diese Klassen nicht in die (Interface-)Dokumentation eingehen müssen. Auch die Arbeit mit IDE's wird einfacher.

    d) Code verstecken
    Die Implementationsdetails könne ja auch eine "trade secret" sein - also PIMPL, und libs o.ä. ausliefern

    e) Compile-Zeiten runtersetzen. Klingt vielleicht dämlich, aber bei großen Projekten haben Build-Zeiten großen Einfluß darauf, welche Methoden man anwenden kann.



  • peterchen schrieb:

    a) Einzige Möglichkeit zur Vermeidung rekursiver Header-Includes (A muß B kennen, und B muß A kennen).

    so nen include-kreis hatte ich mal und wollte wirklich kein pimpl nehmen. habe es so gelöst, daß ich alles zu templates machte und die templetes dürfen ja, solange sie nicht gebraucht werden, allerhand noch nicht wissen. hauptsache, bei der verwendung nachher habe ich beide klassen gelesen.
    könnte sein, daß man daraus eine weitere allgemeine methode stricken könnte, und pimpl nicht mehr die einzige möglichkeit wäre.



  • peterchen schrieb:

    a) Einzige Möglichkeit zur Vermeidung rekursiver Header-Includes (A muß B kennen, und B muß A kennen).

    Ist das nicht genau der Fall wofür man den IncludeGuard benutzt, oder hab ich dich da falsch verstanden 😕



  • @volkard: Ich WUSSTE das irgendeiner angekleckert kommt und ne andere variante auf den Tisch haut 🙄

    @SirLant: Mir fällt grad kein passenes Beispiel ein, aber meine Kollegen schaffen das immer wieder..

    ich probiers...

    // a.h
    #ifndef HEADER_A_H_
    #define HEADER_A_H_
    #include "b.h"
    class Foo
    {
       Bar * b;
    };
    #endif
    
    // b.h
    #ifndef HEADER_B_H_
    #define HEADER_B_H_
    #include "a.h"
    class Bar
    {
      Foo * f;
    };
    #endif
    

    wenn du a.h reinlädst:
    1. HEADER_A_H_ wird definiert
    2. b.h wird angelesen
    3. HEADER_B_H_ wird definiert
    4. bei das #include a.h wird der "Körper" von a.h übersprungen weil HEADER_A_H_
    schon definiert ist. Somit wird a.h noch nicht definiert
    5. Wenn "Foo * f" übersetzt wird, ist Foo noch nicht bekannt

    Hier ist die Lösung simpel: nur eine Forward-Deklaration der jeweils zu zeigernden Klasse (was so ne Art PIMPL für Arme ist). Gibt aber kompliziertere Fälle - wie gesagt, meine Kollegen kennen sich da bestens aus 😉



  • Ok jetzt versteh ich was gemeint ist *g*

    Aber man könnte da doch mit 2Defines arbeiten *hrhrhr*



  • SirLant schrieb:

    Ok jetzt versteh ich was gemeint ist *g*

    Aber man könnte da doch mit 2Defines arbeiten *hrhrhr*

    Oder einfach forward declarieren


Anmelden zum Antworten