2016-06-21 1 views
0

Ich traf einen interessanten Compilierung Fehler, wenn ein kleines Beispiel zu testen:Gibt es einen Unterschied zwischen Kopierkonstruktor/Kopierzuweisung und normaler Funktionsaufrufoptimierung beim Kompilieren?

#include <iostream> 

using namespace std; 

class A 
{ 
public: 
    A() { cout <<"A created." <<endl; } 
    A(A& a) { cout <<"A created by copy constructor." <<endl; } 
    ~A() { cout <<"A destoryed." <<endl; } 
}; 

A CreateObject() 
{ 
    A obj; 
    return obj; 
} 

int main() 
{ 
    A a; 
    A b; 

    b= CreateObject(); 

    return 0; 
} 

es einfach ist und hat keine Probleme überhaupt. es jedoch aufgefordert, bei der Zusammenstellung:

copy_constructor.cpp: In function ‘int main()’: 
copy_constructor.cpp:23: error: no matching function for call to ‘A::A(A)’ 
copy_constructor.cpp:9: note: candidates are: A::A(A&) 

es scheint, dass das Programm versucht Kopierkonstruktors aufrufen beim Kompilieren „b = Create();“ aber es gibt keinen passenden Kopierkonstruktor. das sollte nicht passieren, weil es nur eine Zuweisungsanweisung gibt, gibt es einen Unterschied zwischen Konstruktor und normaler Funktion beim Kompilieren der Optimierung?

+3

: http://coliru.stacked-crooked.com/a/019cc3c18ba2a889. Was sind Ihre Compiler- und Kompilierungsoptionen? – Petr

+3

Der Copy-Konstruktor sollte eine "const" -Referenz nehmen, keine modifizierbare. – Mat

+2

Sind Sie sicher, dass Ihr realer Code nicht wirklich 'A b = CreateObject();' sagt? –

Antwort

1

Dies ist ungültig nach C++ 03 Standard.

In C++ 03, b = CreateObject() kann tatsächlich zu b = A(CreateObject()); erweitern. Dies wurde erst in späteren Versionen von C++ "behoben", wo das Erstellen der temporären Kopie nun verboten ist.

CreateObject() gibt einen R-Hand-Wert zurück, der nur vom Kopierkonstruktor mit einer A(const A& a)-Signatur konsumiert werden kann. Ohne den Modifikator const gilt dies nur für l-Hand-Werte.

z. b = a wäre mit dieser Signatur und der Erweiterung immer noch gültig gewesen, weil Sie innerhalb des Konstruktors a ändern könnten.


Dies ist immer noch replizierbar Einstellung Klirren ++ zu C++ 98-Standard: http://coliru.stacked-crooked.com/a/50c25c469420ab0f

Ältere Versionen von Visual-C++ zeigen den genauen Fehler des OP angezeigt.

g ++ kann dies nicht korrekt überprüfen, selbst wenn C++ 98 explizit angegeben wird.

Siehe Compiliert für mich auch https://stackoverflow.com/a/13898867/2879325

+0

haben Sie die Ursache herausgefunden und tatsächlich lerne ich viel von Ihrer Antwort. Danke! :) –

0

Der Code, den Sie gepostet haben, kompiliert einfach gut. Sie sollten jedoch Ihren Kopierkonstruktor von A(A&) zu A(const A&) ändern.

+0

Danke! @Zwinck, deine Lösung ändert 'A (A &)' in 'A (const A &)' funktioniert wirklich. Ich habe das mit @ Ext3hs Interpretation herausgefunden. –

Verwandte Themen