und - c++ vererbung konstruktor reihenfolge




Sind bei einem Konstruktor ohne Argumente keine Sprachklammern? (6)

Ich kompilierte ein C ++ - Programm in Cygwin mit g ++ und ich hatte eine Klasse, deren Konstruktor keine Argumente hatte. Ich hatte die Zeilen:

MyClass myObj();
myObj.function1();

Und als ich versuchte, es zu kompilieren, bekam ich die Nachricht:

error: request for member 'function1' in 'myObj', which is of non-class type 'MyClass ()()'

Nach ein wenig Nachforschungen fand ich, dass die Lösung darin bestand, diese erste Zeile zu ändern

MyClass myObj;

Ich könnte schwören, dass ich leere Konstruktordeklarationen mit Klammern in C ++ vorher getan habe. Ist das wahrscheinlich eine Einschränkung des Compilers, den ich verwende, oder sagt der Sprachstandard wirklich, dass keine Klammern für einen Konstruktor ohne Argumente verwendet werden?


Der Standard benötigt keine Klammern.

int* x = new int;

ist legale Syntax.

In deinem Fall myclass myobj(); ist ein Funktionsprototyp. Während myclass myobj; ist eine Variable.


Dies ist ein ziemlich bekanntes Problem und ist nicht vom Compiler abhängig. Im Wesentlichen haben Sie eine Funktion deklariert, die den Typ MyObj zurückgibt. Es ist nicht überraschend, dass Sie den Konstruktor nicht aufrufen konnten. Eine gute Erklärung finden Sie in C ++ faq lite


Ich habe dies im C ++ - Standard (§8.5.8) gefunden:

Ein Objekt, dessen Initialisierer ein leerer Satz von Klammern ist, dh, (), wird mit Wert initialisiert.

[Hinweis: da () nicht von der Syntax für den Initialisierer erlaubt ist,

X a ();

ist nicht die Deklaration eines Objekts der Klasse X, sondern die Deklaration einer Funktion, die kein Argument annimmt und ein X zurückgibt. Das form () ist in bestimmten anderen Initialisierungskontexten erlaubt (5.3.4, 5.2.3, 12.6.2). Endnote]


Ihre Zeile myObj , dass der Compiler denkt, dass Sie eine Funktion namens myObj die keine Argumente annimmt und eine MyClass zurückgibt. Diese Mehrdeutigkeitsauflösung ist in der Tat ärgerlich.


Obwohl MyClass myObj(); könnte als Objektdefinition mit einem leeren Initialisierer oder einer Funktionsdeklaration geparst werden. Der Sprachstandard gibt an, dass die Mehrdeutigkeit immer zugunsten der Funktionsdeklaration aufgelöst wird. Ein leerer Klammerninitialisierer ist in anderen Kontexten zulässig, z. B. in einem new Ausdruck oder beim Konstruieren eines temporär initialisierten Wertes .


MyClass myObj();

Das wird als Funktionsdeklaration geparst, die Funktion heißt myObj, nimmt keine Argumente und gibt das MyClass-Objekt zurück. Ich habe noch nie einen Compiler gesehen, der das akzeptiert. Auf der anderen Seite MyClass* myPtr = new MyClass(); ist akzeptabel, kann das dich verwirrt haben?





standards