2012-02-21 11 views
10

Podczas czytania kodu widzę, że:Zamiana wektor z kopią sobie

vector<TypeA>(typeAObj).swap(typeAObj); 

Moje pytanie brzmi

Dlaczego oni zamienić wektor z kopią sobie?

+1

FWIW, [nie ma nic do gwarancji] (http://stackoverflow.com/questions/7829018/can-we-rely-on-the-reduce-capacity-trick). –

+0

Należy zauważyć, że wektor nie jest zamieniany na * sam *, ale raczej na * kopię * samego siebie. –

+0

Napisałem o kopii, Rawicki to zredagował)) –

Odpowiedz

12

To wzór dla skurczowej do montażu w C++ 03, gdzie nie ma takich operacji w interfejsie klasy wektorowych. To, co robi kod, to tworzenie kopii (miejmy nadzieję, że capacity wektora będzie zbliżony do liczby dostępnych elementów), a następnie zamieni go z oryginalnym wektorem. Po zakończeniu wyrażenia tymczasowy (który teraz zawiera oryginalne bufory) zostaje odrzucony, a pamięć zostaje zwolniona.

Rozważmy:

std::vector<int> large; 
large.reserve(10000000); // might be the result of multiple push_back/erase 
// large.capacity() >= 10000000 
large.push_back(1);  // Make more explicit that 'large' might not be empty 
std::vector<int>(large).swap(large); 
// large.capacity() is hopefully closer to 1 

w C++ 11 rodzaj wektor został zmodyfikowany, aby zapewnić shrink_to_fit działanie, które ma na tej roli. Należy zauważyć, że ani stary wzorzec, ani shrink_to_fit nie są operacjami wiążącymi, tj. Nie ma gwarancji na capacity wektora po operacji innej niż capacity() >= size().

+0

Dzięki David! Byłem pewien, że to była jakaś sztuczka z efektem ubocznym. –

+0

"* nie ma gwarancji co do pojemności wektora po operacji innej niż pojemność()> = rozmiar() *" ... Dlaczego tak jest? – Nawaz

+1

@Nawaz: Po prostu jest. Standard C++ wyraźnie stwierdza, że ​​* shrink_to_fit * jest niewiążącym wywołaniem i stwierdza, że ​​nie ma takiej gwarancji. W tym modelu dzieje się to samo, nigdzie w standardzie nie wymaga, aby kopia miała taką samą * pojemność * lub nawet więcej niż oryginalny obiekt. Jedynym wymaganiem dla 'capacity()' jest to, że musi to być co najmniej 'size()' z oczywistych powodów. Poza tym ten idiom działa w wielu implementacjach, aby zmniejszyć pojemność, jeśli jest znacznie większa niż rozmiar. –

8

Uważam, że jest to sposób na "zmniejszenie" wektora do minimalnego rozmiaru.

vector<TypeA>(typeAObj) tworzy kopię wektora, którego zarezerwowany rozmiar może być mniejszy niż oryginał.

Tak więc zamiana wektora na nową kopię może być sposobem na uwolnienie niepożądanej pamięci.