2014-10-30 15 views
48

Koduję w C++. Jeśli mam jakąś funkcję void foo(vector<int> test) i ja nazywam ją w moim programie, czy wektor zostanie przekazany przez wartość lub referencję? Nie jestem pewien, ponieważ wiem, że wektory i tablice są podobne i że funkcja taka jak void bar(int test[]) przeszła testowanie przez odniesienie (wskaźnik?) Zamiast wartości. Domyślam się, że musiałbym przekazać wektor za pomocą wskaźnika/odniesienia jawnie, gdybym chciał uniknąć przekazywania wartości, ale nie jestem pewien.przekazywanie wektorów do funkcji, wartość względem referencji C++

+5

C++ nie „przechodzą przez wartość” semantyki, więc jest przekazywana przez wartość. Możesz zdecydować się przejść przez referencję. Wybór zależy od funkcji. – juanchopanza

+1

użyj referencji, jeśli nie chcesz, aby funkcja zmieniała zawartość wektorową sprawiała, że ​​stała, w przeciwnym razie przekaż ją przez odniesienie. Pozwoli to uniknąć niepożądanego i kosztownego (czasami) kopiowania. –

+2

Ponadto odwołanie nie jest wskaźnikiem. –

Odpowiedz

66

Gdybym musiał zgadnąć, powiedziałbym, że pochodzisz z Java. To jest C++, a rzeczy są przekazywane wartością, chyba że określisz inaczej używając operatora-operatora (uwaga: ten operator jest również używany jako operator "adres-of", ale w innym kontekście). To wszystko jest dobrze udokumentowane, ale będę ponownie iteracji i tak:

void foo(vector<int> bar); // by value 
void foo(vector<int> &bar); // by reference (non-const, so modifyable inside foo 
void foo(vector<int> const &bar); // by const-reference 

Można również zdecydować się przekazać wskaźnik do wektora (void foo(vector<int> *bar)), ale chyba wiesz co robisz i czujesz, że to jest naprawdę droga, nie rób tego.

Również wektory są nie takie same jak tablice! Wewnętrznie wektor śledzi tablicę, której obsługuje zarządzanie pamięcią, ale także wiele innych kontenerów STL. Nie można przekazać wektora do funkcji oczekującej wskaźnika lub tablicy (lub odwrotnie) (można uzyskać dostęp do (wskaźnika) bazowej tablicy i używać tego). Wektory są klasami oferującymi wiele funkcji za pośrednictwem funkcji składowych, natomiast wskaźniki i tablice są wbudowanymi typami. Również wektory są przydzielane dynamicznie (co oznacza, że ​​rozmiar może być określany i zmieniany w czasie wykonywania), podczas gdy tablice w stylu C są statycznie przydzielane (jego rozmiar jest stały i muszą być znane w czasie kompilacji), ograniczając ich użycie.

Proponuję przeczytać trochę więcej o C++ w ogóle (szczególnie array decay), a następnie przyjrzeć się następującym programem który ilustruje różnicę między tablicami i wskaźnikami:

void foo1(int *arr) { cout << sizeof(arr) << '\n'; } 
void foo2(int arr[]) { cout << sizeof(arr) << '\n'; } 
void foo3(int arr[10]) { cout << sizeof(arr) << '\n'; } 
void foo4(int (&arr)[10]) { cout << sizeof(arr) << '\n'; } 

int main() 
{ 
    int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
    foo1(arr); 
    foo2(arr); 
    foo3(arr); 
    foo4(arr); 
} 
+13

Masz mnie. Tło Java. –

+2

Czy ktoś może mi pomóc zrozumieć funkcję foo4 ostatniej deklaracji? Dlaczego zwraca rozmiar tablicy zamiast rozmiaru wskaźnika, tak jak w innych funkcjach? –

+1

@abhishek_M ponieważ typ parametru jest odniesieniem. Odwołanie może być związane tylko z wyrażeniem dokładnie tego samego typu. Z tego powodu tablica nie zanika, ponieważ odwołanie do tablicy nie może być powiązane ze wskaźnikiem, może być związane tylko z tablicą tego samego typu (w tym przypadku tablicą 10 liczb całkowitych) – bolov

5

void foo(vector<int> test)

wektor byłyby przekazywane przez wartość w tym.

masz więcej sposobów, aby zdać wektorów w zależności od kontekstu: -

1) przechodzą przez odniesienie: - To niech funkcja foo zmienić zawartość wektora. Bardziej wydajne niż przekazywanie wartości poprzez unikanie kopiowania wektora.

2) Przejście przez const-reference: - Jest to efektywne i niezawodne, gdy nie chcesz, aby funkcja zmieniała zawartość wektora.

7

A vector jest funkcjonalnie taki sam jak tablica. Ale dla języka vector jest typem, a int jest również typem. Do argumentu funkcji tablica dowolnego typu (w tym vector[]) jest traktowana jako wskaźnik. A vector<int> to nie to samo, co int[] (dla kompilatora). vector<int> jest nie-tablicowy, nie-referencyjny i nie-wskaźnikowy - jest przekazywany przez wartość, a więc wywołuje on konstruktora kopiowania.

Musisz więc użyć vector<int>& (najlepiej z const, jeśli funkcja go nie modyfikuje), aby przekazać go jako odniesienie.

+0

Jaka jest składnia do przekazywania "tablicy wektorów" w odniesieniu do funkcji? – ab123

+0

void functionName (std :: vector (& vc) [5]) {} – RIanGillis

Powiązane problemy