Die allgemeine Antwort wurde bereits von anderen bereitgestellt, einschließlich @ x13n. Ich werde versuchen, etwas detaillierter zu erklären, was der Code wirklich bedeutet.
Die Syntax MyObject ob = anotherMyObject;
entspricht MyObject obj(anotherMyObject);
. Die Bedeutung ist Kopieren Sie das Konstrukt ob
aus dem Objekt anotherMyObject
. Der Compiler wird immer MyObject ob = ...;
mit einem Aufruf des Kopierkonstruktors übereinstimmen (normalerweise MyObject(MyObject const &)
, kann aber auch MyObject(MyObject&)
sein, wenn der Benutzer dies so erklärt).
In Ihrem speziellen Code ist die rechte Seite kein MyObject
, daher kann es nicht als Argument an den Kopierkonstruktor übergeben werden und der Compiler wird versuchen, diese rhs in etwas umzuwandeln, das mit dem Kopierkonstruktor von verwendet werden kann MyObject
Anwendung der allgemeinen Regeln. In Ihrem Fall ist es eine implizite Konstruktor, der ein int
Argument, und das verwendet werden kann, eine temporäres MyObject
zu erstellen, so dass der Compiler schreibt Ihren Code zu sein:
MyObject ob(MyObject(99));
// ^^^ temporary created by the compiler to match the copy constructor
Beachten Sie, dass dies nicht das gleiche ist wie MyObject ob(99)
, aber eine Kombination der int
und kopieren Konstruktoren, auch wenn der Gesamteffekt ähnlich ist. Wenn der Konstruktor, der eine ganze Zahl annimmt, als explicit
deklariert wurde, konnte der Compiler sie nicht zur Bereitstellung der Konvertierung verwenden, und der Code konnte nicht kompiliert werden.
In einem Kommentar zu einer anderen Antwort weist @x13n darauf hin, dass dies kein Aufruf des Kopierkonstruktors ist. Als ob Sie diesem Konstruktor eine Ablaufverfolgung hinzufügen würden, wird die Ablaufverfolgung nicht generiert. Das ist ein völlig anderes Problem, bei dem der Compiler die Kopie optimieren kann, indem er das temporäre in genau der gleichen Adresse erstellt, die ob
nimmt. Dies kann auf zwei Arten verifiziert werden, wobei beide davon abhängig sind, dass der Compiler zwar die Kopie ausliefern kann, aber die gleichen Einschränkungen einhalten muss. So können wir MyObject ob(MyObject(99))
ungültig es zwei Möglichkeiten, entweder Zugriff auf den Copykonstruktor deaktivieren oder Deaktivieren der Aufruf an den Konstruktor mit einem temporären:
class test1 {
test1(test1 const &) {} // make the copy constructor private
public:
test1(int) {}
};
class test2 {
public:
test2(test2 &) {} // make the copy constructor take a non-const reference
// i.e. disable the use of temporaries
test2(int) {}
};
int main() {
test1 t1 = 99; // copy constructor is private in this context
test2 t2 = 99; // g++: no matching function call to test2::test2(test2)
// diagnostics will differ with other compilers
}
Nein, er ist nicht Copykonstruktor aufrufen. Fügen Sie 'MyClass (const MyClass & asdf) hinzu: a (asdf.a) {cout <<" cc call "<< endl;}' zu seinem Code. "cc call" wird nicht gedruckt. – x13n
@ x13n Sie haben Recht, wenn mir das gefällt MyClass obj (99); Meine Klasse ob = obj; dann wird der Kopierkonstruktor – anand
@ x13n heißen: Sie irren sich und das @ Alien01 war richtig an erster Stelle. Die Sprache gibt an, dass "MyClass ob = 99" äquivalent zu "MyClass ob (MyClass (99))" ist. Das heißt, der Compiler erstellt ein temporäres Konstrukt mit dem impliziten Konstruktor und * then * kopiert es dann in das reale Objekt. Der Effekt, den Sie sehen (fehlende Ausgabe von Ihrem Kopierkonstruktor), ist auf eine Optimierung zurückzuführen, bei der der Compiler das Temporäre an der gleichen Stelle wie das resultierende Objekt erstellen kann und somit die Kopie herausnimmt. Um dies zu überprüfen, deklarieren Sie den Kopierkonstruktor als privat und Sie erhalten einen Zugriffsfehler im Code. –