Konstruktory kopiowania i operatory przypisania kopiowania (C++)
Uwaga
Począwszy od języka C++11, w języku obsługiwane są dwa rodzaje przypisania: przypisywanie kopii i przenoszenie przypisania. W tym artykule "przypisanie" oznacza przypisanie kopiowania, chyba że jawnie określono inaczej. Aby uzyskać informacje o przypisaniu przenoszenia, zobacz Move Constructors and Move Assignment Operators (C++)( Przenoszenie konstruktorów i operatorów przypisania przenoszenia (C++).
Zarówno operacja przypisania, jak i operacja inicjowania powodują skopiowanie obiektów.
Przypisanie: gdy wartość jednego obiektu jest przypisywana do innego obiektu, pierwszy obiekt jest kopiowany do drugiego obiektu. W związku z tym ten kod kopiuje wartość
b
doa
elementu :Point a, b; ... a = b;
Inicjowanie: inicjowanie występuje podczas deklarowania nowego obiektu, przekazywania argumentów funkcji według wartości lub zwracania przez wartość z funkcji.
Semantyka "copy" można zdefiniować dla obiektów typu klasy. Na przykład, rozważmy ten kod:
TextFile a, b;
a.Open( "FILE1.DAT" );
b.Open( "FILE2.DAT" );
b = a;
Powyższy kod może oznaczać "skopiowanie zawartości pliku FILE1. DAT do FILE2. DAT" lub może to oznaczać "ignorować PLIK2. DAT i utwórz b
drugą dojście do pliku FILE1.DAT". Należy dołączyć odpowiednią semantyka kopiowania do każdej klasy w następujący sposób:
Użyj operatora
operator=
przypisania, który zwraca odwołanie do typu klasy i przyjmuje jeden parametr przekazywany przezconst
odwołanie — na przykładClassName& operator=(const ClassName& x);
.Użyj konstruktora kopiowania.
Jeśli konstruktor kopiujący nie zostanie zadeklarowany, kompilator wygeneruje konstruktor kopiujący mądry elementu członkowskiego. Podobnie, jeśli operator przypisania kopiowania nie zostanie zadeklarowany, kompilator wygeneruje operator przypisania kopiowania mądrego elementu członkowskiego. Deklarowanie konstruktora kopiowania nie pomija operatora przypisania kopiowania generowanego przez kompilator i odwrotnie. Jeśli zaimplementujesz jedną z nich, zalecamy również zaimplementowanie drugiej. Podczas implementowania obu tych elementów znaczenie kodu jest jasne.
Konstruktor kopiowania przyjmuje argument typu ClassName&
, gdzie ClassName
jest nazwą klasy. Na przykład:
// spec1_copying_class_objects.cpp
class Window
{
public:
Window( const Window& ); // Declare copy constructor.
Window& operator=(const Window& x); // Declare copy assignment.
// ...
};
int main()
{
}
Uwaga
Ustaw typ argumentu const ClassName&
konstruktora kopiowania, jeśli jest to możliwe. Zapobiega to przypadkowej zmianie skopiowanego obiektu przez konstruktora kopiowania. Umożliwia również kopiowanie z const
obiektów.
Konstruktory kopii wygenerowane przez kompilator
Konstruktory kopiowania generowane przez kompilator, takie jak konstruktory kopiowania zdefiniowane przez użytkownika, mają jeden argument typu "odwołanie do nazwy klasy". Wyjątek występuje, gdy wszystkie klasy bazowe i klasy składowe mają konstruktory kopii zadeklarowane jako przyjmujący jeden argument nazwy-klasy typuconst
&. W takim przypadku argument konstruktora kopiowania wygenerowanego przez kompilator jest również const
.
Gdy typ argumentu do konstruktora kopiowania nie const
jest , inicjalizacja przez skopiowanie const
obiektu generuje błąd. Odwrotnie nie ma wartości true: jeśli argument to const
, można zainicjować, kopiując obiekt, który nie const
jest .
Operatory przypisania generowane przez kompilator są zgodne z tym samym wzorcem dla elementu const
. Przyjmują jeden argument typu ClassName&
, chyba że operatory przypisania we wszystkich klasach bazowych i składowych przyjmują argumenty typu const ClassName&
. W tym przypadku wygenerowany operator przypisania dla klasy przyjmuje const
argument.
Uwaga
Gdy wirtualne klasy bazowe są inicjowane przez konstruktory kopii, niezależnie od tego, czy są generowane przez kompilator, czy zdefiniowane przez użytkownika, są inicjowane tylko raz: w momencie ich konstruowania.
Implikacje są podobne do konstruktora kopiowania. Gdy typ argumentu nie const
jest , przypisanie z const
obiektu generuje błąd. Odwrotnie nie ma wartości true: jeśli const
wartość jest przypisana do wartości, która nie const
jest , przypisanie powiedzie się.
Aby uzyskać więcej informacji na temat przeciążonych operatorów przypisania, zobacz Przypisywanie.
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla