Warum erstellt dieser Aufruf durch Verweis eine neue Instanz?

8

Im Aufruf einer Methode foo by const ref :

%Vor%

Dieser Codeabschnitt kompiliert nicht nur, er erstellt eine neue Instanz von Entity mit seinen Standardwerten im Bereich von foo . Ich würde erwarten, dass dies nicht kompiliert oder zumindest abstürzt.

Wenn ich foo richtig anrufe ( foo(*e) ), funktioniert alles wie erwartet und ich sehe die richtigen Werte von Entity in foo .

Ich verwende mingw, das mit Qt 4.7 geliefert wird.

Hier ist die Schnittstelle von Entity :

%Vor%     
atamanroman 20.09.2011, 13:03
quelle

3 Antworten

15

[Edited] Sie haben einen impliziten Konvertierungskonstruktor (der auch ist zufällig ein Standardkonstruktor) von Entity* (über parent QObject* ) nach Entity und er wird zum Erstellen verwendet eine temporäre Instanz zum Übergeben.

Aus diesem Grund schlage ich immer vor, alle aufrufbaren Konstruktoren mit Einzelparametern explizit zu machen (z. B. wenn alle Parameter bis auf einen voreingestellt sind) und implizite Konvertierungsoperatoren zu vermeiden, außer wenn sie genau die Semantik der Konvertierung ausführen das wäre unter allen Umständen zu erwarten. In anderen Fällen stellen Sie die Konvertierungen über explizite Methoden zur Verfügung.

Es gibt gelegentlich Fälle, in denen implizite Conversions sinnvoll sind und jede von Fall zu Fall ausgewertet werden sollte.

    
Mark B 20.09.2011, 13:12
quelle
2

Eigentlich:

%Vor%

Sie erstellen eine neue temporäre Entität von einem Zeiger auf eine Entity (die auch ein Zeiger auf ein QObject ist).

Es kompiliert, weil es gültig ist.

Wie Mark hervorgehoben hat, wird die implizite Konvertierung von Entity * in Entity über den Konstruktor durchgeführt, der ein Argument vom Typ "pointer to QObject" verwendet. Um dies zu testen, ändern Sie die Vererbung in private, Sie sollten einen Kompilierungsfehler erhalten.

Um solche Fehler in Zukunft zu vermeiden, deklarieren Sie Conversion-Konstruktoren als explicit .

    
Luchian Grigore 20.09.2011 13:23
quelle
1

Ihr Entity -Konstruktor nimmt ein QObject* -Argument und ist nicht als explicit markiert. Das bedeutet, dass ein Entity implizit aus einem Entity* konstruiert werden kann, was ziemlich schlechte Nachrichten sind.

Da die Funktion außerdem ref-to const benötigt, kann dieses implizit konstruierte temporäre Objekt an dieses Funktionsargument gebunden werden.

Markieren Sie den Konstruktor explicit .

    
quelle

Tags und Links