Komische Objektinitialisierung



  • Hi!

    Hab ein Problem entdeckt das sich mir nicht ganz erschließt:

    A a; // aufruf von default c'tor
    A a(); // geht nich da dies als funktionsdeklaration interpertiert wird
    A a( 1 ); // aufruf von überladenem c'tor
    A a = A(); // aufruf vom copy c'tor, equivalent zu A a( A() );
    A a = A( 1 ); // aufruf vom copy c'tor, equivalent zu A a( A( 1 ) );
    

    Soweit sogut, nun habe ich folgende Klasse:

    class Base
    {
    protected:
    	Base()
    	{}
    
    	Base( int i )
    	{}
    };
    
    class Derived : public Base
    {
    public:
    	Derived( int i ) : Base( i )
    	{
    		Base a; // 1
    		Base a( 1 ); // 2
    		Base a = Base(); // 3
    		Base a = Base( 1 ); // 4
    	}
    };
    

    1 und 2 bringen Fehler, da die entsprechenden Konstruktoren ja geschützt sind. 4 bringt auch einen Fehler da Base( int ) geschützt ist aber 3 kompiliert.

    Mein erster Gedanke war, der copy c'tor ist ja public ergo: ein Objekt kann kopiert werden aber: Wieso kann ein temporäres Objekt angelegt werden wenn der default c'tor doch geschützt ist?

    Zweiter Gedanke: Der copy c'tor hat das Recht ein Objekt zu erzeugen, egal ob der Konstruktor geschützt ist oder nicht. Aber: Wieso funktioniert dann ein überladener Konstruktor nicht?

    Nun habe ich den copy c'tor mal geschützt und siehe da, 3. kompiliert nichtmehr also liegt es tatsächlich am copy c'tor. Was aber nicht erklärt das 4. nicht auch funktioniert.
    Außerdem wurde der copy c'tor garnicht aufgerufen (über irgendwelche Ausgaben getestet) sondern direkt der standard c'tor.

    Nun habe ich im Internet gesucht und auf einer Microsoft Entwickler Page folgendes gefunden:

    This means that

    A a = A();

    is treated as if it is direct-initialization and this means that the copy constructor is not invoked.

    Das würde also erklären warum der copy c'tor nicht aufgerufen wurde. Aber ist das tatsächlich konform? Ich hab nichts dergleichen finden können im Standard.
    Und zu allem Elend kompiliert der g++ den obigen Code nicht und bringt die, von mir egtl erwartete, Meldung das der default c'tor protected ist.

    Viele Grüße

    Edit: Vergessen zu erwähnen, auf VS (2003 und 2005) kompiliert den Code.



  • g++ ist da scheinbar anderer Meinung:

    darthdespotism@akazieLX:~$ g++ main.cpp
    main.cpp: In constructor »Derived::Derived(int)«:
    main.cpp:4: Fehler: »Base::Base()« ist geschützt
    main.cpp:16: Fehler: in diesem Zusammenhang
    
    darthdespotism@akazieLX:~$ g++ --version
    g++ (GCC) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)
    Copyright (C) 2006 Free Software Foundation, Inc.
    Dies ist freie Software; die Kopierbedingungen stehen in den Quellen. Es
    gibt KEINE Garantie; auch nicht für MARKTGÄNGIGKEIT oder FÜR SPEZIELLE ZWECKE.
    
    darthdespotism@akazieLX:~$ cat main.cpp
    class Base 
    { 
    protected: 
        Base() 
        {} 
    
        Base( int i ) 
        {} 
    }; 
    
    class Derived : public Base 
    { 
    public: 
        Derived( int i ) : Base( i ) 
        { 
            Base a = Base(); // 3 
        } 
    };
    
    int main()
    {
    
    }
    


  • Genau, hab ich bereits getestet (steht auch im Post ;)). Ich vermute ja das es ein Bug in VC++ ist.



  • It's not a bug, it's a feature.

    BTW: Comeau ist derselben Meinung wie gcc.



  • David_pb schrieb:

    Genau, hab ich bereits getestet (steht auch im Post ;)). Ich vermute ja das es ein Bug in VC++ ist.

    Uups hab ich überlesen.



  • ist ein bug, ja. die MS-entwickler gestehen in sich sogar ein, aber finden es nicht so wichtig - ergo wird er nicht korrigiert. tja.

    dazu gabs vor zwei, drei wochen schonmal nen thread. ich finde ihn gerade nicht, aber die betreffende stelle im standard, die MS falsch interpretiert, ist 8.5/14/4/2.



  • Hm... Dacht ichs mir doch! 😉 Danke für die Antworten!


Anmelden zum Antworten