Frage - Klasseninitialisierung



  • Das hier funktioniert bei mir nicht, mit "explicit" oder ohne "explicit":

    #include <iostream>
    using namespace std;
    
    class Foo
    {
        public:
        explicit Foo(int a);
        private:
        int m_x;
    };
    
    Foo::Foo(int a)
    :m_x(a)
    {
    
    }
    
    class Bar
    {
        public:
        Bar(const Foo &foo);
        private:
        Foo m_y;
    };
    
    Bar::Bar(const Foo &foo)
    :m_y(foo)
    {
    
    }
    
    int main()
    {
       Bar b = 42; // dies führt jetzt zu einem Fehler!
    }
    

    Außerdem wäre für den Compiler "Bar b = 42" u. "Bar b = Foo(42)" immer --> Bar b = Bar(Foo(42));???

    Und was ist jetzt eigentlich nochmal die Poente von "explicit"? Was soll damit verhindert bzw. bezweckt werden? Wo liegt der Sinn?

    MfG
    Stromberg



  • Stromberg schrieb:

    Und was ist jetzt eigentlich nochmal die Poente von "explicit"? Was soll damit verhindert bzw. bezweckt werden? Wo liegt der Sinn?

    class a_explicit
    {
    public:
        a_explicit() {}
        explicit a_explicit(int a){}
    };
    
    class a_implicit
    {
    public:
        a_implicit() {}
        a_implicit(int a){}
    };
    
    void foo_e(a_explicit const& ae)
    {
    }
    
    void foo_i(a_implicit const& ai)
    {
    }
    
    void bar()
    {
        foo_e(1); // geht nicht
        foo_i(1); // geht schon
    
        a_explicit ae;
        a_implicit ai;
        ae = 1; // geht nicht
        ai = 1; // geht schon
    }
    

    Der Sinn ist also implizite Konvertierungen zu "verbieten" wo sie sonst erlaubt wären. Und das ist meistens das was man möchte. -> einfach immer "explicit" vor jeden Ctor schreiben, ausser man möchte ganz bewusst implizite Konvertierungen erlauben (wie z.B. std::string::string(const char*) damit man String-Literale verwenden kann wo ein std::string erwartet wird).



  • Muss ich eigentlich eine implizite Initialisierung als "copy initialization" ansehen, oder kann ich das auch als "direct initialization" ansehen, weil eigentlich ist es doch so, das "(...)" == "=..." ist oder?
    int a=10;
    int a(10);
    ???
    Also:

    class A; //Konstruktor implizit
    
    int main()
    {
        A=12; //Passiert da dann dass hier --> A=A(12) --> Kopierkonstruktor
              //oder dass hier --> A(12) --> normaler Konstruktor
        return 0;
    }
    

    Oder kann man das nicht so genau sagen, da es immer irgendwie als Konstruktor weg optimiert wird? Oder wie läuft das nochmal ab?

    MfG
    Stromberg



  • Soweit ich weiß benutzt der Compiler da immer den normalen Konstruktor, außer auf der rechten Seite ist auch ein Objekt vom Typ A, dann natürlich den Copy-Konstruktor



  • Initialisierung mit "A a = 12;" ist copy initialization, wobei aber der copy-ctor "elided" (weggelassen) werden darf.
    Ist also AFAIK äquivalent zu "A a = A(12);" bzw. "A a(A(12));".



  • Wie man sich täuschen kann 🤡


Anmelden zum Antworten