I vettori vengono passati alle funzioni per valore o per riferimento in C ++


94

Sto programmando in C ++. Se ho una funzione void foo(vector<int> test)e la chiamo nel mio programma, il vettore verrà passato per valore o riferimento? Non sono sicuro perché so che i vettori e gli array sono simili e che una funzione come void bar(int test[])potrebbe passare il test per riferimento (puntatore?) Invece che per valore. La mia ipotesi è che avrei bisogno di passare il vettore tramite puntatore / riferimento esplicitamente se volessi evitare di passare per valore, ma non ne sono sicuro.


5
C ++ ha la semantica "passa per valore", quindi viene passato per valore. Puoi decidere di passare per riferimento però. La scelta dipende davvero da cosa fa la funzione.
juanchopanza

2
usa per riferimento, se non vuoi che la funzione cambi il contenuto del vettore rendilo const, altrimenti passalo semplicemente per riferimento.
Eviterà

3
Inoltre, un riferimento non è un puntatore.
The Paramagnetic Croissant

2
@AliKazmi Tranne se vuoi una copia nel corpo della funzione.
juanchopanza

Dipende da cosa vuoi ottenere. L'uso di uno dei puntatori intelligenti standard a volte è utile, ad esempio se si desidera trasferire la proprietà, quindi utilizzare unique_ptr. Ma di solito passo std :: vector per riferimento.
Erik Alapää

Risposte:


134

Se dovessi indovinare, direi che provieni da un background Java. Questo è C ++, e le cose vengono passate per valore a meno che non specifichi diversamente usando l' &operatore-(nota che questo operatore è usato anche come operatore 'indirizzo di', ma in un contesto diverso). È tutto ben documentato, ma lo ripeterò comunque:

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

Puoi anche scegliere di passare un puntatore a un vettore ( void foo(vector<int> *bar)), ma a meno che tu non sappia cosa stai facendo e senti che questa è davvero la strada da percorrere, non farlo.

Inoltre, i vettori non sono gli stessi degli array! Internamente, il vettore tiene traccia di un array di cui gestisce la gestione della memoria per te, ma anche molti altri contenitori STL. Non puoi passare un vettore a una funzione che si aspetta un puntatore o un array o viceversa (puoi accedere a (puntatore a) l'array sottostante e usarlo però). I vettori sono classi che offrono molte funzionalità attraverso le sue funzioni membro, mentre i puntatori e gli array sono tipi incorporati. Inoltre, i vettori vengono allocati dinamicamente (il che significa che la dimensione può essere determinata e modificata in fase di esecuzione) mentre gli array in stile C sono allocati staticamente (la sua dimensione è costante e deve essere nota in fase di compilazione), limitandone l'uso.

Ti suggerisco di leggere un po 'di più sul C ++ in generale (in particolare il decadimento degli array ), e poi dare un'occhiata al seguente programma che illustra la differenza tra array e puntatori:

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);
}

2
Qualcuno può aiutarmi a capire l'ultima dichiarazione funzione foo4? Perché restituisce la dimensione dell'array invece della dimensione del puntatore come in altre funzioni?
abhishek_M

3
@abhishek_M perché il tipo di parametro è un riferimento. Un riferimento può essere associato solo a un'espressione dello stesso identico tipo. Per questo motivo l'array non decade, poiché un riferimento a un array non può essere associato a un puntatore, può essere associato solo a un array dello stesso tipo (in questo caso array di 10 interi)
bolov

1
c ++ 11 ha "semantica di spostamento" e puoi farlo con attenzione e passare per valore (con semantica di spostamento) senza copia. Ecco un link che mi ha aiutato molto: mbevin.wordpress.com/2012/11/20/move-semantics
fchen

23

A vectorè funzionalmente uguale a un array. Ma per la lingua vectorè un tipo, ed intè anche un tipo. Per un argomento di funzione, un array di qualsiasi tipo (incluso vector[]) viene considerato come puntatore. A vector<int>non è uguale a int[](per il compilatore). vector<int>è non array, non riferimento e non puntatore: viene passato per valore e quindi chiamerà copy-costruttore.

Quindi, è necessario utilizzare vector<int>&(preferibilmente con const, se la funzione non la modifica) per passarlo come riferimento.


Qual è la sintassi per passare un "array di vettori" in riferimento a una funzione?
ab123

void functionName (std :: vector <int> (& vc) [5]) {}
RIanGillis

9

void foo(vector<int> test)

vettore verrebbe passato per valore in questo.

Hai più modi per passare i vettori a seconda del contesto: -

1) Passa per riferimento: - Ciò consentirà alla funzione pippo di modificare il contenuto del vettore. Più efficiente del passaggio per valore in quanto si evita la copia del vettore.

2) Passa per riferimento const: - Questo è efficiente e affidabile quando non vuoi che una funzione modifichi il contenuto del vettore.


1

quando passiamo vettore per valore in una funzione come argomento, crea semplicemente la copia di vettore e nessun effetto si verifica sul vettore che è definito nella funzione principale quando chiamiamo quella particolare funzione. mentre quando passiamo vettore per riferimento qualunque cosa sia scritta in quella particolare funzione, ogni azione verrà eseguita sul vettore che è definito in main o altra funzione quando chiamiamo quella particolare funzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.