Interne Funktion



  • Hallo,

    ich habe in meinem System einige Funktionen, die eigentlich nur vom System aufgerufen werden. Z.B. ruft eine Klasse Foo eine Methode Bar::methode() auf. Bar::methode() sollte eigentlich nicht vom Benutzer meines System direkt aufgerufen werden, aber manchmal braucht er das vielleicht doch.

    Wie markiere ich so eine Funktion am besten? Nur in der Doku vermerken oder die Info in den Namen packen, zb die Methode _methode() nennen?



  • Eine Möglichkeit wäre, Foo zum friend von Bar zu machen und Bar::methode() private zu deklarieren. Damit sollte man aber bestenfalls sparsam umgehen weil friend-Beziehungen so ziemlich die stärkste Abhängigkeit sind, die man in C++ ausdrücken kann.
    Evtl. lässt sich das Design noch verbessern, dass so eine Abhängigkeit wie du sie schilderst nicht auftritt.



  • Ich finde friend class Foo bedeutet immer: "Du, Klasse Foo, GEHÖRST jetzt zu meiner Schnittstelle." Das passt in meinem Fall aber nicht.

    Das Design kann ich nicht groß ändern. Es gibt halt einige Funktionen, die der Benutzer nicht aufrufen SOLLTE. Aber wenn er genau weiß was er tut, dann ist es auch ok wenn er es macht. Ich glaub ich nehm den Unterstrich (hab ich schon in einigen Projekten gesehen)



  • Das ist das Problem/Segen an den eingebauten Mechanismen. Sie sind so strikt. 😉

    Ich würde da auch einfach eine ganz normale öffentliche Funktion nehmen und dann einfach vermerken, dass sie nur mit Bedacht genutzt werden sollte. Schliesslich sollte beim programmieren immer mitgedacht werden..



  • drakon schrieb:

    Das ist das Problem/Segen an den eingebauten Mechanismen. Sie sind so strikt. 😉

    Ich würde da auch einfach eine ganz normale öffentliche Funktion nehmen und dann einfach vermerken, dass sie nur mit Bedacht genutzt werden sollte. Schliesslich sollte beim programmieren immer mitgedacht werden..

    Finde ich schlecht. Dadurch verschlechtert man das Interface bzw. dessen Absicherung gegen Fehlbenutzung. Die Abhängigkeit bleibt dabei weiterhin bestehen. Es wird also nichts gewonnen. Ich würde dafür friends benutzen.



  • Tachyon schrieb:

    drakon schrieb:

    Das ist das Problem/Segen an den eingebauten Mechanismen. Sie sind so strikt. 😉

    Ich würde da auch einfach eine ganz normale öffentliche Funktion nehmen und dann einfach vermerken, dass sie nur mit Bedacht genutzt werden sollte. Schliesslich sollte beim programmieren immer mitgedacht werden..

    Finde ich schlecht. Dadurch verschlechtert man das Interface bzw. dessen Absicherung gegen Fehlbenutzung. Die Abhängigkeit bleibt dabei weiterhin bestehen. Es wird also nichts gewonnen. Ich würde dafür friends benutzen.

    Das ist doch dann aber nicht mehr die gleiche Funktionalität. Wenn ich die Methoden private mache, dann hat der Benutzer ja garkeine Möglichkeit mehr sie manuell aufzurufen? 😕


  • Mod

    Und wenn man die Methode in

    namespace foo_internals___use_with_caution 
    {
    }
    

    packt?



  • Finde ich schlecht. Dadurch verschlechtert man das Interface bzw. dessen Absicherung gegen Fehlbenutzung.

    C++ ist nicht dazu gedacht, irgendwas gegen Fehlbenutzung abzusichern. Siehe C++ FAQ LITE 7.6 und 7.7 .

    Mache die besagten Funktionen oeffentlich und versehe sie mit einem Kommentar: only for internal use.



  • SeppJ schrieb:

    Und wenn man die Methode in

    namespace foo_internals___use_with_caution 
    {
    }
    

    packt?

    Dann benutzt man einen reservierten Bezeichner (doppelte Underscores) :p



  • Und was spricht dagegen, die Funktion protected zu machen, so dass man ableiten muss um an diese Funktion zu kommen? Denn wenn es ein äußerst seltener Spezialfall sein sollte, spricht eigentlich einiges für eine eigene Klasse.


  • Administrator

    Registrierter Troll schrieb:

    Dann benutzt man einen reservierten Bezeichner (doppelte Underscores) :p

    Nur wenn diese am Anfang des Bezeichners auftauchen, ist es ein reservierter Bezeichner. In der Mitte oder am Ende ist es völlig egal.

    Grüssli



  • hmmmmm schrieb:

    Und was spricht dagegen, die Funktion protected zu machen, so dass man ableiten muss um an diese Funktion zu kommen? Denn wenn es ein äußerst seltener Spezialfall sein sollte, spricht eigentlich einiges für eine eigene Klasse.

    Mir fallen da so ca 100 Gründe ein.
    Ich mach sie jetzt einfach public und vermerke den "internal use" in der Doku.



  • Dravere schrieb:

    Nur wenn diese am Anfang des Bezeichners auftauchen, ist es ein reservierter Bezeichner. In der Mitte oder am Ende ist es völlig egal.

    Das verwechselst du wohl gerade mit einem einzelnen Underscore.

    17.4.3.1.2 Global names schrieb:

    Certain sets of names and function signatures are always reserved to the implementation:
    — Each name that contains a double underscore (_ _) or begins with an underscore followed by an upper case letter (2.11) is reserved to the implementation for any use.

    17.4.3.1.3 External linkage schrieb:

    Each name having two consecutive underscores (2.11) is reserved to the implementation for use as a name with both extern "C" and extern "C++" linkage.



  • knivil schrieb:

    Finde ich schlecht. Dadurch verschlechtert man das Interface bzw. dessen Absicherung gegen Fehlbenutzung.

    C++ ist nicht dazu gedacht, irgendwas gegen Fehlbenutzung abzusichern. Siehe C++ FAQ LITE 7.6 und 7.7 .

    Mache die besagten Funktionen oeffentlich und versehe sie mit einem Kommentar: only for internal use.

    Die C++ FAQ bestätigt meine Aussage.
    Die Aussage ist "Encapsulation prevents mistakes, not espionage.". Und zwischen "private sehen können" und "gar nicht erst private machen" ist schon ein Unterschied, gelle?

    Also knivel->Epic fail. Merke: Sicherheit != Sicherheit. 😉

    Es wird dort auch Folgendes über friends gesagt: friends

    Öffentliche Interfaces sollte so sicher wie möglich gegen Falschbenutzung gesichert sein. Das gilt im verschärften Maße für Bibliotheken.
    Was nicht öffentlich sein soll, soll nicht öffentlich sein. Das ist irgendwie in sich schon logisch. Wenn man Mittel hat, die Kapselung zu erhöhen, sollte man das auch tun.

    Warum sollte man "only for internal use" ins öffentliche Interface schreiben, wenn man das besser über friends designen kann, und es dann eben auch wirklich nur intern benutzt werden kann? Du lässt ja auch nicht Deinen Darm aus Deinem After heraushängen, nur weil er gelgentlich mit der Toilette korrospondiert. Merke: Die Toilette ist Deine Freund. 🤡

    Siehe auch Item 18 und 19 in "Effective C++".

    PS: Die "interne" Funktion soll aber ganz offenslichtlich nicht wirklich intern sein. Also mache sie halt öffentlich.


  • Administrator

    @Registrierter Troll,
    😮
    Ich muss ein paar Namen ändern gehen 😃
    Danke für die Aufklärung, hatte das anders im Kopf.

    Grüssli



  • Ich denke wenns wirklich am Design nicht besser hinzubiegen ist (was ich erst glaube wenn ichs sehe), dann ist das mit der protected methode der richtige Weg - und zwar mit private Vererbung:

    class Foo
    {
    public:
      meh();
    protected:
      methode();
    };
    
    class Bar : private Foo //statt Foo als Member zu haben.
    {
      void baz()   
      {
        methode(); // (!)
      }
    };
    


  • pumuckl schrieb:

    Ich denke wenns wirklich am Design nicht besser hinzubiegen ist (was ich erst glaube wenn ichs sehe), dann ist das mit der protected methode der richtige Weg - und zwar mit private Vererbung:

    class Foo
    {
    public:
      meh();
    protected:
      methode();
    };
    
    class Bar : private Foo //statt Foo als Member zu haben.
    {
      void baz()   
      {
        methode(); // (!)
      }
    };
    

    Und wieso ist das besser als friend ? Die Bindung ist doch noch viel stärker.



  • Tachyon schrieb:

    Und wieso ist das besser als friend ? Die Bindung ist doch noch viel stärker.

    Nope. Friend-Bindung ist noch stärker als Vererbung (weil friend eben auch Zugriff auf private Elemente erlaubt, Vererbung nicht).



  • pumuckl schrieb:

    Tachyon schrieb:

    Und wieso ist das besser als friend ? Die Bindung ist doch noch viel stärker.

    Nope. Friend-Bindung ist noch stärker als Vererbung (weil friend eben auch Zugriff auf private Elemente erlaubt, Vererbung nicht).

    Okay, da ist was dran.



  • Wie ich bereits sagte, ich mach die Methode public und vermerke in der Doku, dass man sie eher nicht verwenden sollte. Aber eben KANN. Drum macht private absolut keinen Sinn. Vererbung gleich 3mal nicht, da die Klassen nicht zum Ableiten designed sind und es auch nie werden.

    @Tachyon: Mach mal hier lieber nicht auf dicken Macker. So der Oberchecker biste ja offenbar auch nicht, gelle? 😉


Anmelden zum Antworten