Подтвердить что ты не робот

Передача векторов в функцию, значение vs reference С++

Я программирую на С++. Если у меня есть некоторая функция void foo(vector<int> test), и я вызываю ее в своей программе, будет ли вектор передаваться по значению или ссылке? Я не уверен, потому что я знаю, что векторы и массивы похожи и что функция типа void bar(int test[]) будет проходить тест по ссылке (указатель?) Вместо значения. Я предполагаю, что мне нужно было бы передать вектор по указателю/ссылке явно, если бы я хотел избежать передачи по значению, но я не уверен.

4b9b3361

Ответ 1

Если бы я должен был догадаться, я бы сказал, что вы из фона Java. Это С++, и все передается по значению, если вы не указали иначе использование & -оператора (обратите внимание, что этот оператор также используется как оператор "адрес-из", но в другом контексте). Все это хорошо документировано, но я все равно повторюсь:

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

Вы также можете передать указатель на вектор (void foo(vector<int> *bar)), но если вы не знаете, что делаете, и чувствуете, что это действительно так, не делайте этого.

Кроме того, векторы не совпадают с массивами! Внутри вектор отслеживает массив, из которого он обрабатывает управление памятью для вас, но так же многие другие контейнеры STL. Вы не можете передать вектор функции, ожидающей указателя или массива, или наоборот (вы можете получить доступ к (указателю на) базовый массив и использовать это, хотя). Векторы - это классы, предлагающие множество функций через свои функции-члены, тогда как указатели и массивы - это встроенные типы. Кроме того, векторы динамически распределяются (что означает, что размер может быть определен и изменен во время выполнения), тогда как массивы C-стиля статически распределены (его размер является постоянным и должен быть известен во время компиляции), ограничивая их использование.

Я предлагаю вам прочитать больше о С++ вообще (в частности, распад массива), а затем взглянуть на следующую программу, которая иллюстрирует разницу между массивами и указателями

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

A vector функционально аналогичен массиву. Но, для языка vector является тип, а int также является типом. К аргументу функции массив любого типа (включая vector[]) рассматривается как указатель. A vector<int> не совпадает с int[] (компилятору). vector<int> не является массивом, не ссылкой и не указателем - он передается по значению, и, следовательно, он будет вызывать copy-constructor.

Итак, вы должны использовать vector<int>& (желательно с const, если функция не модифицирует его), чтобы передать его как ссылку.

Ответ 3

void foo(vector<int> test)

вектор будет передан по значению в этом.

У вас есть больше способов передать векторы в зависимости от контекста: -

1) Передайте по ссылке: - Это позволит функции foo изменить содержимое вашего вектора. Более эффективно, чем пропускать по значению как копирование вектора.

2) Передача по const-reference: - Это эффективно и надежно, когда вы не хотите, чтобы функция меняла содержимое вектора.

Ответ 4

Я понимаю, что вопрос отвечает. Я хотел бы подчеркнуть еще один важный аспект:

Если вектор имеет определенный пользователем тип данных, то тип должен реализовать соответствующую конструкцию копирования, чтобы вектор мог быть модифицирован функцией, где он называется ссылкой, если функция обновляет вектор в результате push_back локальной переменной этого UDT.

Итак, если вы проходите

vector<A> vA;

к функции

void foo(vector<A> &vA){  

  A a;

  vA.push_back(a);
// do something with the vector
}

тогда класс A должен иметь конструктор копирования, определенный для того, чтобы функция могла обновлять вектор.

class A{
   ..
   int x;

   void A(A& orig){
     this->x = orig.x;
    }

};

Ответ 5

когда мы передаем вектор по значению в функцию в качестве аргумента, он просто создает копию вектора, и никакой эффект не происходит с вектором, который определен в основной функции, когда мы вызываем эту конкретную функцию. в то время как когда мы передаем вектор по ссылке все, что написано в этой конкретной функции, каждое действие будет выполняться над вектором, который определен в основной или другой функции, когда мы вызываем эту конкретную функцию.