2013-05-09 14 views
7

W C++, jeśli masz do pętli, która „kopie” obiektów przez użytkownika określonego typu przy użyciu konstruktora poruszać, czy to robi jakąś różnicę jeśli używasz ++i lub i++ jako licznik pętli?konstruktor Move i preinkrementuj vs post-przyrostu

Wiem, że to pytanie wydaje się dość niejasne, ale byłem (jak sądzę) zadałem to pytanie w wywiadzie telefonicznym. Nie byłem pewien, czy dobrze zrozumiałem pytanie, a osoba przeprowadzająca wywiad uznała to za nie znające odpowiedzi i przerwała krótką rozmowę.

Do czego on zmierza?

+0

Zobacz także Herb Sutter [GotW # 2 Solution: Temporary Objects] (http://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/). – jww

Odpowiedz

10

W C++, jeśli masz do pętli że „kopie” obiektów o zdefiniowanym przez użytkownika przy użyciu konstruktora typu ruch [...]

przede wszystkim konstruktor ruch jest używany do move-constructing, co zwykle oznacza, że ​​nie "kopiujesz": możesz wykonać ruch jako kopiowanie - w rzeczywistości klasa, która jest konstruktywna pod względem kopiowania, również jest ruchoma - ale dlaczego właśnie definiujesz konstruktor ruchu?

[...] Czy robi to jakąś różnicę, jeśli używasz ++ i lub i ++ jako licznika pętli?

To zależy od tego, co jest i. Jeśli jest to obiekt skalarny, taki jak int, to nie ma żadnej różnicy.

Jeśli i to klasa typu iterator, z drugiej strony, ++i powinny być bardziej wydajne (na gruncie czysto teoretycznej), ponieważ realizacja operator ++ nie będzie musiał tworzyć kopię iterator zostać zwrócone przed sam iterator jest inkrementowany.

Oto, na przykład, jest jak stdlibC++ definiuje operatory inkrementacji dla typu iteratora wystąpienia std::list:

_Self& 
operator++() 
{ 
    _M_node = _M_node->_M_next; 
    return *this; 
} 

_Self 
operator++(int) 
{ 
    _Self __tmp = *this; 
    _M_node = _M_node->_M_next; 
    return __tmp; 
} 

Jak widać, wersja postfix (jeden przyjmującej obojętne int) ma więcej pracy zrobić: musi utworzyć kopię oryginalnego iteratora, który ma być odwrócony, a następnie zmienić wewnętrzny wskaźnik iteratora, a następnie zwrócić kopię.

Z drugiej strony, wersja prefiksu musi jedynie zmienić wewnętrzny wskaźnik i powrót (odniesienie do).

Należy jednak pamiętać, że przy wykonywaniu pomiarów wszystkie założenia muszą być poparte pomiarem. W tym przypadku nie oczekuję żadnej sensownej różnicy między tymi dwiema funkcjami.

+1

Mam go na części "kopiowanie". Wiedziałem, że nie powinienem używać tego słowa. To nie ma nic wspólnego z konstrukcją ruchomą per se, prawda? Ma to związek z ints vs iterators? – Scott

+0

@Scotta: Rzeczywiście tak jest. Mam zamiar rozszerzyć odpowiedź na przykład –

+0

Andy, jeśli rhs jest lwartością, wtedy ruch będzie niebezpieczny, prawda? –