explicit



  • Hallo Leute!
    Ich habe eine Bitte, ich verstehe das Konzept nicht welches hinter explicit steht. Ich habe gegooglt und selbst etwas experimentiert, was dieses keyword für einen nutzen hat... . Ich würde mich freuen wenn mir hier jemand genauer erläutern könnte was es damit auf sich hat und wo man es verwenden sollte.

    MfG yihaaa



  • explicit verhindert die implizite Typumwandlung von dem Typ des Arguments, das ein Konstruktor als einzigen Parameter nimmt.
    Beispiel:

    struct A
    {
      A(int)
      {}
    };
    struct B
    {
      explicit B(int)
      {}
    };
    
    A a = 5; // geht
    B b = 5; // geht nicht
    B c(5); // geht
    
    void foo(A a);
    void bar(B b);
    
    int main()
    {
      foo(7); // geht
      bar(7); // geht nicht 
    }
    


  • könnte auch interessant sein:
    http://www.c-plusplus.net/forum/304837



  • Danke erst mal! Wie ich deim Beispiel entnehmen konnte sorgt explicite dafür, dass eine Klasse, etc... immer nur direkt initialisiert werden darf? Also mit den ( ) und nicht über Kopierkonstruktor oder Zuweisungsoperator?

    MfG



  • Na ja, mehr oder weniger. Korrekter wäre, wie erwähnt, dass es keine implizite Konvertierung von dem Argumenttyp zum "eigentlichen" Typ gibt. 😉



  • Ich wiederhol mich: Was soll das bringen? Also jetzt mal rein praktisch. Oder gibt's keinen praktischen Grund und man will nur komisch aussehende Zuweisungen verhindern?



  • Incocnito schrieb:

    Oder gibt's keinen praktischen Grund und man will nur komisch aussehende Zuweisungen verhindern?

    Komisch aussehende Zuweisungen zu verhindern ist ein ziemlich praktischer Grund. 🙄



  • Nee, für mich ist das nur Ästhetik und Ästhetik ist für mich Stil. Ich find's nur merkwürdig, dass man für soetwas, was man kinderleicht nachbauen kann, extra ein Schlüsselwort einführt.



  • Solch "komisch aussehende" Zuweisungen sehen bisweilen so unauffällig aus, daß sich die vertracktesten Fehler dahinter hartnäckig verbergen können.



  • Ein Beispiel wäre z.B. eine Container-Klasse, die man mit einem int initialisieren kann, um die Anzahl der Elemente festzulegen (geht z.B. bei std::vector)

    Angenommen diese Klasse würde jetzt auch noch den operator == überladen, mit dem man überprüfen kann, ob alle Elemente beider Container identisch sind,
    so wäre das hier ein valider Code:

    Container foo(5);
    if (foo == 23)
    {
        // ...
    }
    

    Hier würde implizit ein temporärer Container mit 23 Elementen erzeugt und dann verglichen, was jenseits jeder Logik ist...

    Durch einen expliziten Konstruktor wird eben diese Konversion unterbunden.

    Es gibt noch andere Situationen, wo man durch explicit Mechanismen des Compilers gezielt verbietet.

    Ein Beispiel sind auch die neuen expliziten Cast-Operatoren (C++11).
    Man kann jetzt also explicit auch vor Cast-Operatoren platzieren um implizite Umwandlungen zu unterbinden.
    Eine Anwendung dafür sind Smart Pointer, welche früher auf das Safe-Bool-Idiom zurückgreifen mussten.

    Das Hauptproblem, welches man mit explicit bekämpfen möchte, ist also, dass implizite Konversionen in Verbindung mit diversen Operatoren zu unerwartetem Verhalten führen. (Unerwartet hier z.B. für den Nutzer einer Bibliothek, der nicht besser weiß, was passiert und eigentlich etwas anderes vorhatte...)



  • yihaaa schrieb:

    Danke erst mal! Wie ich deim Beispiel entnehmen konnte sorgt explicite dafür, dass eine Klasse, etc... immer nur direkt initialisiert werden darf? Also mit den ( ) und nicht über Kopierkonstruktor oder Zuweisungsoperator?
    MfG

    Das ist so auch nicht richtig, der Copy-Konstruktor wird hier in keiner Weise angetastet ebensowenig wie der Zuweisungsoperator. Einzig und alleine implizite Konversionen werden unterbunden.
    Denn 5 ist z.B. vom Typ int und nicht vom Typ B.

    B b1 = B(5); // das geht z.B. auch, ist allerdings in der Regel schlechter als b2
    B b2(5);
    


  • Incocnito schrieb:

    Nee, für mich ist das nur Ästhetik und Ästhetik ist für mich Stil. Ich find's nur merkwürdig, dass man für soetwas, was man kinderleicht nachbauen kann, extra ein Schlüsselwort einführt.

    Ok. Dann bau mal nach ohne Schlüsselwort. Bin gespannt.


Log in to reply