Piszę w C ++. Jeśli mam jakąś funkcję void foo(vector<int> test)
i wywołam ją w moim programie, czy wektor zostanie przekazany przez wartość lub odniesienie? Nie jestem pewien, ponieważ wiem, że wektory i tablice są podobne i że funkcja taka jak void bar(int test[])
może przejść test przez odniesienie (wskaźnik?) Zamiast według wartości. Domyślam się, że musiałbym jawnie przekazać wektor przez wskaźnik / odniesienie, jeśli chciałbym uniknąć przekazywania wartości, ale nie jestem pewien.
97
Odpowiedzi:
Gdybym miał zgadywać, powiedziałbym, że pochodzisz z języka Java. To jest C ++ i rzeczy są przekazywane przez wartość, chyba że określisz inaczej za pomocą
&
-operator (zwróć uwagę, że ten operator jest również używany jako operator „address-of”, ale w innym kontekście). To wszystko jest dobrze udokumentowane, ale i tak powtórzę:void foo(vector<int> bar); // by value void foo(vector<int> &bar); // by reference (non-const, so modifiable inside foo) void foo(vector<int> const &bar); // by const-reference
Możesz także zdecydować się na przekazanie wskaźnika do wektora (
void foo(vector<int> *bar)
), ale jeśli nie wiesz, co robisz i czujesz, że tak naprawdę jest do zrobienia, nie rób tego.Poza tym wektory to nie to samo co tablice! Wewnętrznie wektor śledzi tablicę, w której zarządza pamięcią, ale tak samo postępuje wiele innych kontenerów STL. Nie możesz przekazać wektora do funkcji oczekującej wskaźnika lub tablicy lub odwrotnie (możesz uzyskać dostęp do (wskaźnika do) tablicy bazowej i użyć tego). Wektory to klasy oferujące wiele funkcji poprzez swoje funkcje składowe, podczas gdy wskaźniki i tablice są typami wbudowanymi. Ponadto wektory są przydzielane dynamicznie (co oznacza, że rozmiar można określić i zmienić w czasie wykonywania), podczas gdy tablice w stylu C są przydzielane statycznie (ich rozmiar jest stały i musi być znany w czasie kompilacji), co ogranicza ich użycie.
Sugeruję, abyś przeczytał trochę więcej o C ++ w ogóle (szczególnie rozpad tablic ), a następnie rzucił okiem na następujący program, który ilustruje różnicę między tablicami a 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); }
źródło
Funkcjonalnie A
vector
jest taka sama jak tablica. Ale językvector
jest typem iint
jest też typem. W przypadku argumentu funkcji tablica dowolnego typu (w tymvector[]
) jest traktowana jako wskaźnik. Avector<int>
to nie to samo coint[]
(dla kompilatora).vector<int>
nie jest tablicą, nie jest odwołaniem i nie jest wskaźnikiem - jest przekazywana przez wartość, a zatem wywoła konstruktor kopiujący.Więc musisz użyć
vector<int>&
(najlepiej withconst
, if function go nie modyfikuje), aby przekazać go jako referencję.źródło
void foo(vector<int> test)
wektor zostanie przekazany przez wartość w this.
Masz więcej sposobów przekazywania wektorów w zależności od kontekstu: -
1) Przekaż przez referencję: - To pozwoli funkcji foo zmienić zawartość wektora. Bardziej wydajne niż przekazywanie wartości, ponieważ unika się kopiowania wektora.
2) Przekaż przez odniesienie do stałej: - Jest to wydajne i niezawodne, gdy nie chcesz, aby funkcja zmieniała zawartość wektora.
źródło
kiedy przekazujemy w funkcji wektor po wartości jako argument, po prostu tworzy kopię wektora i nie ma żadnego wpływu na wektor, który jest zdefiniowany w funkcji głównej, kiedy wywołujemy tę konkretną funkcję. podczas gdy gdy przekażemy wektor przez odniesienie, cokolwiek jest zapisane w tej konkretnej funkcji, każda akcja będzie wykonywana na wektorze, który jest zdefiniowany w funkcji głównej lub innej, kiedy wywołujemy tę konkretną funkcję.
źródło