Problem mit gesperrtem Kopierkonstruktor und anschließender Initialisierung



  • Ich habe folgendes Testprogramm:

    class Klasse
    {
    public:
    
    	Klasse (int wert=0)
    	{
    	}
    
    	void operator = (int wert)
    	{
    	}
    
    private:
    
    	Klasse (const Klasse &objekt);
    	void operator = (const Klasse &objekt);
    };
    
    int main ()
    {
    	Klasse objekt1=5;
    	Klasse objekt2 (5);
    	Klasse objekt3;
    
    	objekt3=5;
    }
    

    Wie man sehen kann, habe ich den Kopierkonstruktor und den =-Operator, die jeweils eine Referenz derselben Klasse übernehmen, gesperrt, denn es soll nicht möglich sein, die Objekte aufeinander zu kopieren. Allerdings habe ich einen Konstruktor und einen =-Operator, die jeweils eine Zahl entgegennehmen können. Was mich nun wundert: Sowohl in Zeile 21, als auch in Zeile 22 wird ja dieser (öffentliche, nicht gesperrte) Konstruktor aufgerufen. Und trotzdem gibt er mir für Zeile 21 den Fehler

    test.cpp:15: error: `Klasse::Klasse(const Klasse&)' is private
    test.cpp:21: error: within this context

    während er für Zeile 22 keine Fehler anzeigt und auch alles fehlerfrei kompiliert, wenn ich Zeile 21 auskommentiere.

    Ich würde nun gerne wissen, warum das so ist. Wenn ich den Kopierkonstruktor sperre und einen anderen Konstruktor erstelle, der einen Wert entgegennimmt, warum kann ich diesen per

    Klasse objekt (wert);
    

    aufrufen, aber nicht mit

    Klasse objekt=wert;
    

    Hätte ich den Kopierkonstruktor in Zeile 15 nicht gesperrt, sondern komplett rausgeschmissen, hätte auch alles funktioniert.


  • Mod

    Das Verhalten der Produktion

    T x = y;
    

    wird definiert als

    T x = T( y );
    

    Es wird also ein temporäres Objekt vom Typ T erstellt (unter Benutzung eines geeigneten Konstruktors) und dieses Objekt dann kopiert zur Erstellung von x. Es ist zulässig für den Compiler, die Erzeugung des temporären Objekts und die Kopie auszulassen und dafür x direkt zu konstruieren. Der Standard verlangt aber auch in diesem Falle, dass der Kopierkonstruktor zumindest aufrufbar wäre. Das ist nicht der Fall, also bricht der Compiler ab.

    Hätte ich den Kopierkonstruktor in Zeile 15 nicht gesperrt, sondern komplett rausgeschmissen, hätte auch alles funktioniert.

    Das liegt daran, dass dann der Compiler einen Kopierkonstruktor deklariert, der public ist. Als Grundsatz: jede Klasse hat einen Destruktor und (wenigstens) einen Kopierkonstruktor. Es ist schlicht unmöglich, eine Klasse zu definieren, auf die das nicht zutrifft. Im Einzelfall können dieser Konstruktor oder Destruktor nicht definiert werden - aber das ist eine andere Frage.



  • Aha. Es gibt also keine Möglichkeit, in meinem Falle = zu schreiben, richtig?


Anmelden zum Antworten