C++
Kopiowanie a przypisanie
Szukaj…
Składnia
- Kopiuj konstruktora
- MyClass (const MyClass i inne);
- MyClass (MyClass i inne);
- MyClass (lotna stała MyClass i inne);
- MyClass (lotna MyClass i inne);
- Konstruktor zadań
- MyClass & operator = (const MyClass & rhs);
- MyClass & operator = (MyClass & rhs);
- MyClass & operator = (MyClass rhs);
- const MyClass & operator = (const MyClass & rhs);
- const MyClass & operator = (MyClass & rhs);
- const MyClass & operator = (MyClass rhs);
- Operator MyClass = (const MyClass & rhs);
- Operator MyClass = (MyClass & rhs);
- Operator MyClass = (MyClass rhs);
Parametry
rhs | Prawa strona równości dla konstruktorów kopiowania i przypisywania. Na przykład konstruktor przypisania: MyClass operator = (MyClass & rhs); |
---|---|
Symbol zastępczy | Symbol zastępczy |
Uwagi
Inne dobre zasoby do dalszych badań:
Jaka jest różnica między operatorem przypisania a konstruktorem kopiowania?
Operator przypisania
Operator przypisania ma miejsce, gdy zamieniasz dane na już istniejący (poprzednio zainicjowany) obiekt na dane innego obiektu. Weźmy to jako przykład:
// Assignment Operator
#include <iostream>
#include <string>
using std::cout;
using std::endl;
class Foo
{
public:
Foo(int data)
{
this->data = data;
}
~Foo(){};
Foo& operator=(const Foo& rhs)
{
data = rhs.data;
return *this;
}
int data;
};
int main()
{
Foo foo(2); //Foo(int data) called
Foo foo2(42);
foo = foo2; // Assignment Operator Called
cout << foo.data << endl; //Prints 42
}
Widzicie tutaj, wzywam operatora przypisania, gdy już zainicjowałem obiekt foo
. Później przypisuję foo2
do foo
. Wszystkie zmiany pojawiające się po wywołaniu tego operatora znaku równości są zdefiniowane w funkcji operator=
. Możesz zobaczyć wyjście do uruchomienia tutaj: http://cpp.sh/3qtbm
Kopiuj konstruktora
Natomiast konstruktor kopiowania jest całkowitym przeciwieństwem konstruktora przypisania. Tym razem służy do inicjalizacji już nieistniejącego (lub nie zainicjowanego wcześniej) obiektu. Oznacza to, że kopiuje wszystkie dane z obiektu, do którego je przypisujesz, bez faktycznej inicjalizacji kopiowanego obiektu. Teraz spójrzmy na ten sam kod jak poprzednio, ale zmodyfikuj konstruktor przypisania, aby był konstruktorem kopiującym:
// Copy Constructor
#include <iostream>
#include <string>
using std::cout;
using std::endl;
class Foo
{
public:
Foo(int data)
{
this->data = data;
}
~Foo(){};
Foo(const Foo& rhs)
{
data = rhs.data;
}
int data;
};
int main()
{
Foo foo(2); //Foo(int data) called
Foo foo2 = foo; // Copy Constructor called
cout << foo2.data << endl;
}
Możesz zobaczyć tutaj Foo foo2 = foo;
w głównej funkcji natychmiast przypisuję obiekt przed faktycznym zainicjowaniem go, co, jak powiedziano wcześniej, oznacza, że jest to konstruktor kopii. I zauważ, że nie musiałem przekazywać parametru int dla obiektu foo2
ponieważ automatycznie foo2
poprzednie dane z obiektu foo. Oto przykładowy wynik: http://cpp.sh/5iu7
Kopiuj Konstruktor kontra Konstruktor przydziału
Ok, krótko przyjrzeliśmy się temu, co konstruktor kopiowania i konstruktor przypisania są powyżej, i podaliśmy przykłady każdego z nich, zobaczmy teraz oba w tym samym kodzie. Ten kod będzie podobny jak powyżej dwóch. Weźmy to:
// Copy vs Assignment Constructor
#include <iostream>
#include <string>
using std::cout;
using std::endl;
class Foo
{
public:
Foo(int data)
{
this->data = data;
}
~Foo(){};
Foo(const Foo& rhs)
{
data = rhs.data;
}
Foo& operator=(const Foo& rhs)
{
data = rhs.data;
return *this;
}
int data;
};
int main()
{
Foo foo(2); //Foo(int data) / Normal Constructor called
Foo foo2 = foo; //Copy Constructor Called
cout << foo2.data << endl;
Foo foo3(42);
foo3=foo; //Assignment Constructor Called
cout << foo3.data << endl;
}
Wynik:
2
2
Tutaj możesz zobaczyć, że najpierw wywołujemy konstruktor kopiowania, wykonując wiersz Foo foo2 = foo;
. Ponieważ nie zainicjowaliśmy tego wcześniej. Następnie wywołujemy operatora przypisania na foo3, ponieważ był on już zainicjowany foo3=foo
;