2010-02-03 9 views

Odpowiedz

26

Tak i Nie

Pierwszym jest inicjowany wyraźnie, a druga kopia jest inicjowany. Standardy pozwalają zastąpić drugi z pierwszym. W praktyce wytworzony kod jest taki sam.

Oto, co się dzieje w pigułce:

std::string s1("foo"); 

Konstruktor ciąg postaci:

string (const char * s); 

nazywa dla s1.

W drugim przypadku. Tworzony jest tymczasowy, a wspomniany konstruktor earler jest wezwany do tego tymczasowego. Następnie wywoływany jest konstruktor kopii. np .:

string s1 = string("foo"); 

W praktyce druga forma jest zoptymalizowana, aby być w postaci pierwszej. Nie widziałem kompilatora, który nie zoptymalizuje drugiego przypadku.

+0

Konstruktor kopiowania nie zostanie wywołany w drugim przypadku, tylko łańcuch (const char * s) zostanie wywołany. To inicjalizacja kopii. Sprawdź: [jak-c-niejawnie przekonwertuj-c-string-string-na-string-obiekt] (http://stackoverflow.com/questions/35568612/how-c-imicic -convert-c-style- string-to-a-string-object) – expoter

-5

Pierwsza jest lepsza.

Drugi utworzy instancję i przypisze wartość domyślną (""). Wtedy będzie przypisanie secodn: "foo". Tak więc 2 przypisania zamiast 1 ...

+7

Nie, drugi nie wywołuje operatora przypisania. –

13

Na pierwszy rzut oka wywoływany jest konstruktor const char* w celu inicjowania s1. Drugi używa konstruktora const char* do zainicjowania wartości tymczasowej, a następnie używa konstruktora kopiowania, przekazując odniesienie do tej wartości tymczasowej, aby zainicjować s2.

Jednak średnia wyraźnie zezwala na coś o nazwie „kopia elizja”, co oznacza, że ​​jak mówi Arak, drugi może legalnie zostać zastąpiony pierwszym nawet jeśli konstruktor kopia ma dostrzegalnych skutków ubocznych, tak że zmiana wpływa na wyjście programu.

Jednak po wymianie kompilator nadal musi sprawdzić, czy klasa ma dostępny konstruktor kopii. Potencjalna różnica polega na tym, że druga forma wymaga wywołania konstruktora kopii, mimo że kompilator nie musi tego wywoływać. Oczywiście nie ma jednej, więc w tym przypadku nie robi różnicy, ale dla innych klas może.

+1

Masz +1 dla "standard wyraźnie zezwala na coś zwanego" copy elision ";) – AraK

+0

Drobna spowiedź: po wysłaniu zauważyłem, że jest to" kopia konstruktywnej elizacji "w indeksie, ale o ile pamiętam, odniosłem się do tego jako "copy elision" :-) –

Powiązane problemy