2012-12-19 12 views
8

Powiel możliwe:
How to pass objects to functions in C++?
Why pass by const reference instead of by value?Zasady pomocą odwołań w C++

W C++ jest tam pewien rodzaj reguły lub kierunkiem dokładnie kiedy trzeba, a przynajmniej powinien zdecydować do używania przekazywania przez referencje niż przez wartość?

I jeśli chodzi o rozmiar obiektu z jakimś przedmiotem, o ile wiem (trochę szczerze) może być trudno osądzać.

+0

Zobacz tę odpowiedź: http://stackoverflow.com/a/114351/6345 (Pointer vs. Reference) –

+0

To samo pytanie było zadawane tak wiele razy na tej stronie ... http://stackoverflow.com/questions/2139224/how-to-pass-objects-to-functions-in-c – nogard

+0

Nieco dobra zasada: 'if (sizeof (SomeType)> sizeof (void *)) // Użyj referencji' –

Odpowiedz

7

Powinieneś przekazać odwołanie za każdym razem, gdy chcesz, aby zmiany w argumentach były widoczne poza funkcją. Jest to odniesienie o numerze innym niż const i jest głównie motywowane raczej logiką niż wydajnością.

Powinieneś podać (głównie const) odniesienie, gdy masz do czynienia z typami danych o rozmiarze większym niż rejestr. Ponieważ odniesienie to w większości jest const, nie można wprowadzać w nim żadnych zmian, więc jest to motywowane efektywnością.

+0

Przekazywanie według wartości jest często szybsze niż odniesienie nawet dla większych obiektów, ponieważ brak 'ograniczenia'. – Pubby

+0

Uwaga: nawet w przypadku małego typu danych obecność ręcznie spreparowanego konstruktora kopii powinna zachęcić użytkownika do użycia 'const &'. Idiomatycznym przykładem jest 'shared_ptr', nie jest tak lekki, jak wielu ludzi myśli. –

3
  1. Jeśli nie chcesz wywoływać konstruktora kopiowania obiektu (na przykład, jeśli jest to ekspansywne ze względu na rozmiar obiektu).
  2. Kiedy rzeczywiście trzeba odniesienia, a nie tylko wartość (swap(a,b), na przykład - ponieważ rzeczywiście trzeba oryginalne odniesienia w celu dokonania swap.)
3

Normalnie używam podanie przez odniesienie w następujących sytuacjach:

1) objetc rozmiar jest większy niż wskaźnik: W tym przypadku, jeśli nie chcę nie modyfikować objetc użyć const odniesienia:

Reference object; 

foo(object); 

z foo zadeklarowane jako:

void foo(const Reference & object); 

2) Dla kodu wyjaśnienia, starając się uniknąć thigs tak:

int f1 = xxx; 
int f2 = yyy; 
int f3 = zzz; 
.... 

foo(f1, f2, ............) 

stosując struct:

struct X 
{ 
    int f1; 
    int f2; 
    int f3; 
    .... 
}; 

X x; 
x.f1 = xxx; 
..... 

foo(X); 

z foo zdefiniowany jako:

foo(const X & x); 

3) dla przyspieszenia: pamiętaj, że funkcje wywołujące muszą ustawić par ametry na stosie 4) Musisz zmodyfikować parametry wewnątrz funkcji.

Reference object; 

foo(object); 

z foo zadeklarowane jako:

void foo(Reference & object); 
1

Wolę pass-by-reference-to-const do pass-by-value. Przekazywanie według wartości jest kosztowną operacją, ponieważ kopie obiektu są tworzone przez producentów kopii.Ponadto, jeśli masz jakieś niepochodzące z prymitywu elementy danych w klasie (np.: std::string), za każdym razem, gdy zostanie utworzony nowy obiekt klasy, zostaną utworzone również obiekty std::string.

Przekazywanie przez odniesienie pozwala również uniknąć slicing problem. Jeśli obiekt klasy pochodnej zostanie przekazany według wartości do funkcji oczekiwanej dla obiektu klasy podstawowej, pochodne cechy klasy pochodnej zostaną odcięte, a obiekt wewnątrz tej funkcji będzie zachowywał się jako obiekt klasy bazowej. Jeśli przejdziesz przez referencję, możesz uniknąć krojenia.

Niemniej jednak są pewne przypadki, w których nie można przejść przez odniesienie. Jeśli argumenty funkcji lub zwracana wartość muszą mieć wartości NULL, nie można używać odwołań.