2012-04-02 16 views
5

Czy ktoś mógłby mi wyjaśnić różnicę między kopiowaniem a przypisaniem?kopiowanie i przydzielanie

SomeClass a; 
SomeClass b = a; // assignment 
SomeClass c(a); // assignment 
b = c; // copying 

ale jaka jest różnica, dlaczego w języku występują dwie różne konstrukcje?

+1

co nazywasz „przypisanie” jest w rzeczywistości nazywa się „inicjalizacji”, a to, co nazywamy „kopiowanie” nazywany jest „zadanie”. – Philipp

+4

'SomeClass a();' - To jest deklaracja funkcji. –

+0

Możliwy duplikat: http://stackoverflow.com/questions/5368258/the-copy-constructor-and-assignment-operator –

Odpowiedz

1

Kopiowanie służy do inicjowania nowych obiektów poprzez kopiowanie zawartości już istniejących, przypisanie służy do nadpisywania istniejących obiektów zawartością innych obiektów - te dwie rzeczy są bardzo różne. W szczególności

SomeClass a; 
SomeClass b = a; 

jest kopia inicjalizacji - jesteś kopiowania a aby utworzyć nowy SomeClass nazywa b użyciem składni formularza

T x = y; 

To ma wpływ na wywoływanie SomeClass „s skopiować konstruktora (zakładając, że jest jeden i jest dostępny). Generowany przez kompilator domyślny konstruktor kopiowania wykonałby kopię zgodną z prawem: a; w razie potrzeby można go zastąpić własnym, np.

SomeClass(const SomeClass& rhs) 
: x(rhs.x) 
{} 

(Należy pamiętać, że jest to bardzo nudne przykład, jak to po prostu robi to, co domyślne memberwise skopiować konstruktora potęgę.)

Idąc dalej, to

SomeClass c(a); 

jest bezpośredni inicjalizacji przy użyciu konstruktora kopii. Będzie to na ogół mają taki sam efekt jak wyżej, ale to jest warta odczytu:

http://www.gotw.ca/gotw/036.htm

Również zobaczyć tutaj:

http://www.gotw.ca/gotw/001.htm

końcowego sprawę, a mianowicie

b = c; 

jest zadaniem. Semantyką tego powinno być na ogół nadpisanie b z zawartością c (chociaż niektóre rzeczy, takie jak std::auto_ptr, mają dziwną semantykę przypisania, więc uważaj). Aby zaimplementować własną operatora przypisania, piszesz coś takiego (zauważ, że jest to bardzo nudne przykład, jak to po prostu robi to, co domyślny memberwise operator przypisania może):

SomeClass& operator=(const SomeClass& rhs) 
{ 
    x = rhs.x; 
    return *this; 
} 

W praktyce jednak trzeba uważaj na wyjątkowe bezpieczeństwo w sytuacjach takich jak ten, co prowadzi do takich rzeczy, jak popularny język do kopiowania i zamiany w celu implementacji operatorów przydziału. Zobacz tutaj:

http://en.wikibooks.org/wiki/More_C++_Idioms/Copy-and-swap

2

To inicjalizacji (ale wywołuje konstruktor kopia):

SomeClass b = a; 

Więc to:

SomeClass c(a); 

To zadanie:

b = c; 

Aha, i to isn't an initialization :

SomeClass a(); 
+0

różnica - przydział działa na obiekcie 'już utworzonym' podczas kopiowania na nowo skonstruowanym obiekcie, który wcześniej nie istniał. –

1

Inicjalizacje inicjują wcześniej niezainicjowany obiekt. Przypisania z kolei powodują nadpisanie już zainicjowanego obiektu i mogą zniszczyć istniejący stan. Są to różne operacje; podczas gdy zwykle mają ten sam wynik dla obiektu na LHS, nie są semantycznie równoważne.

3

Inicjowanie następuje tylko raz, gdy obiekt zostanie utworzony. Jeśli przez kopiowanie masz na myśli wywołanie konstruktora kopiowania, kopiowanie jest formą inicjalizacji. Przypisanie może się zdarzyć dowolną liczbę razy.

Teraz na swoim przykładzie, wszystkie z nich są błędne:

SomeClass a(); 

ten deklaruje metodę zwaną a która przyjmuje żadnych parametrów i zwraca obiekt SomeClass.

SomeClass b = a; // actually copy constructor & initialization of b 
SomeClass c(a); // same 

Jeśli a były SomeClass obiektu, te dwa byłoby inicjowanie i wywołuje konstruktor kopiujący - SomeClass::SomeClass(const SomeClass&). Są one równoważne.

b = c; // assignment 

Jeśli c jest SomeClass obiektu, to jest przyporządkowanie. To callse SomeClass::operator =(const SomeClass&).

Powiązane problemy