expicit - Konvertierung verhindern



  • Hey ihr,

    Wie ihr es euch vermutlich bereits denken könnt ;), habe ich wieder mal ein Verständnisproblem in C++.

    In meinem Buch wurde soeben das Schlüsselwort 'explicit' eingeführt.
    In dem Kapitel ging es um Konstruktoren und das indem man dem Konstruktor das Wort explicit voranstellt eine Konvertierung vom Übergabeparameter des Konstruktors zum Klassentyp verhindert wird.

    Ich verstehe aber nicht, was dann der Konstruktor noch bringen soll.
    Der konstruktor initialisiert das Objekt für das er aufgerufen wurde.
    Doch wenn man ihn wegen explicit nicht mehr aufrufen kann, oder er nicht mehr konvertieren kann bringt er doch nichts.

    Zudem verstehe ich nicht zu 100%, was mit Konvertieren gemeint ist.
    Der Konstruktor konvertier doch nicht- er initialisiert lediglich.

    Wäre nett wenn mir jemand helfen könnte.

    cya
    David



  • Der Konstruktor konvertiert nicht, aber die Sprache C++ für Dich. Bei expliziten Konstruktoren finden solche Konvertierungen hingegen nicht statt. Aber ein Beispiel sagt oft mehr als 1000 Worte:

    class Vector
    {
    public:
        explicit Vector(size_t groesse);
    };
    
    Vector v = 12; // Compilerfehler
    

    Wäre der Konstruktor nicht explicit, wäre die letzte Zeile erlaubt. Rein semantisch ergibt sie aber keinen Sinn ("Huch, ein Vector mit dem Wert 12? Der Größe 12? Oder soll 12 das erste Element sein?" - jedenfalls kein verständlicher Kandidat). Oder noch drastischer:

    std::ifstream ifs = "Hallo, Welt";
    

    Wäre der Konstruktor von ifstream nicht explicit, wäre dies möglich und würde die Datei "Hallo, Welt" öffnen. Aber schön sieht das nicht aus, oder? Zumal man damit ziemlich Schindluder treiben kann (in Situationen, wo man so eine Konvertierung nicht auf Anhieb sieht z.B.).



  • LordJaxom schrieb:

    Wäre der Konstruktor nicht explicit, wäre die letzte Zeile erlaubt. Rein semantisch ergibt sie aber keinen Sinn ("Huch, ein Vector mit dem Wert 12? Der Größe 12? Oder soll 12 das erste Element sein?" - jedenfalls kein verständlicher Kandidat). Oder noch drastischer:

    (keine zeit für mehr)
    das argument zieht bei

    vector<int> x(12);
    

    aber doch genauso...



  • Hier sieht man finde ich aber deutlicher, dass etwas konstruiert, und nichts konvertiert wird. Drastischer wird es z.B. bei Parameterübergabe:

    void func(vector<int> vec);
    
    // ohne explicit:
    func(12); // erkennt jemand, was gemeint ist? ;)
    
    // mit explicit:
    func(vector<int>(12));
    


  • Vector v = 12;

    Durch '=' wird also der Konstruktor aufgerufen.

    Oder durch ()

    Vector v(12);

    Wenn der Konstruktor mehr Argumente erwartet so:

    Vector v(12,n);

    Kann man mit dem '=' was ähnliches machen?

    v = 12,n ...

    Oder muss man über den '.'-Operator jedes Element einzeln ändern, wenn man neu zuweisen will?

    Nur so ne Frage am Rand

    cya
    David



  • 777 schrieb:

    Vector v = 12;

    Durch '=' wird also der Konstruktor aufgerufen.

    Oder durch ()

    Vector v(12);

    Das ruft beides den Ctor auf - die erste Variante ist für explizite Konstruktoren allerdings nicht erlaubt. Als dritte Möglichkeit gibt es noch:

    Vector v = Vector(12);
    

    Wenn der Konstruktor mehr Argumente erwartet so:

    Vector v(12,n);

    Kann man mit dem '=' was ähnliches machen?

    Die expliziten Varianten ("Vector v(12,n);" und "Vector v=Vector(12,n);") lassen sich mit beliebig vielen Parametern verwenden, die implizite Variante "Vector v=12;" gibt es nur für Ctoren, die genau mit einem Argument aufgerufen werden können (und nicht als 'explicit' gekennzeichnet sind).



  • Super- ihr habt mir echt geholfen.

    Vektor v = Vektor(12);

    musste man doch in Ansi C immer sagen.
    In C++ isses dann doch einfach vereinfacht worden- daher gibts noch die 3. Möglichkeit, ne?



  • 777 schrieb:

    Vektor v = Vektor(12);

    musste man doch in Ansi C immer sagen.
    In C++ isses dann doch einfach vereinfacht worden- daher gibts noch die 3. Möglichkeit, ne?

    in C konnte man sowas garnicht sagen, es sei den Vektor() wäre eine Funktion gewesen. Konstruktoren gibt es erst seit C++

    Und Vereinfachung würde ich nicht sagen. Explizite Konstruktoren haben schlicht und ergreifend den großen Vorteil das man nicht so einfach Fehler macht wie bei impliziten.

    cu André


Anmelden zum Antworten