向量是通过值传递还是通过C ++中的引用传递给函数


94

我在用C ++编写代码。如果我有一些函数,void foo(vector<int> test)并且在程序中调用了该函数,则该矢量将通过值或引用传递吗?我不确定,因为我知道向量和数组相似,并且类似的函数void bar(int test[])会通过引用(指针?)而不是值通过测试。我的猜测是,如果我想避免按值传递,但我不确定必须通过指针/引用传递向量。


5
C ++具有“按值传递”的语义,因此按值传递。您可以决定通过引用传递。选择实际上取决于函数的功能。
juanchopanza 2014年

2
按引用使用,如果您不希望函数更改矢量内容使其为const,否则,只需按引用传递即可。它将避免不必要和昂贵的复制(有时)
Ali Kazmi

3
另外,引用不是指针。
顺磁牛角包

2
@AliKazmi除非您要在函数主体中复制。
juanchopanza

这取决于您要实现的目标。使用标准智能指针之一有时会很有用,例如,如果您想传递所有权,请使用unique_ptr。但是通常,我通过引用传递std :: vector。
ErikAlapää2014年

Answers:


133

如果我不得不猜测,我会说你来自Java背景。这是C ++,除非您使用&-operator 另行指定,否则事情将按值传递(请注意,此运算符也用作“ address-of”运算符,但使用的是不同的上下文)。这一切都有据可查,但是我还是要重申:

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

您也可以选择将指针传递给向量(void foo(vector<int> *bar)),但是除非您知道自己在做什么,否则您会觉得这确实是可行的方法,请不要这样做。

另外,向量与数组一样!在内部,向量跟踪它为您处理内存管理的数组,但是其他许多STL容器也是如此。您不能将向量传递给需要指针或数组的函数,反之亦然(您可以访问(指向)基础数组并使用它)。向量是通过其成员函数提供许多功能的类,而指针和数组是内置类型。同样,向量是动态分配的(这意味着可以在运行时确定和更改大小),而C样式的数组是静态分配的(其大小是恒定的,必须在编译时知道),从而限制了它们的使用。

我建议您从总体上了解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
有人可以帮助我了解最后声明foo4函数吗?为什么它返回数组的大小而不是像其他函数那样返回指针的大小?
abhishek_M

3
@abhishek_M,因为参数类型是引用。引用只能绑定到完全相同类型的表达式。因此,数组不会衰减,因为无法将对数组的引用绑定到指针,所以只能将数组绑定到相同类型的数组(在本例中为10个整数)
bolov

1
c ++ 11具有“移动语义”,您可以仔细地进行操作并按值传递(带有移动语义),而不进行复制。这是一个对我有很大帮助的链接:mbevin.wordpress.com/2012/11/20/move-semantics
fchen

23

A vector在功能上与数组相同。但是,语言vector是一种类型,int也是一种类型。对于函数参数,任何类型的数组(包括vector[])都被视为指针。A vector<int>int[](对于编译器)不同。vector<int>是非数组,非引用和非指针-由值传递,因此将调用copy-constructor。

因此,您必须使用vector<int>&(最好是使用const,如果函数未对其进行修改)将其作为参考传递。


通过引用函数传递“向量数组”的语法是什么?
ab123

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

9

void foo(vector<int> test)

向量将在此按值传递。

您有更多的方法可以根据上下文传递矢量:-

1)通过引用传递:-这将使函数foo更改矢量的内容。由于避免了向量的复制,因此比按值传递更有效。

2)通过const-reference传递:-当您不希望函数更改矢量内容时,这既有效又可靠。


1

当我们在函数中按值传递向量作为参数时,它只是创建向量的副本,并且在调用该特定函数时,对主函数中定义的向量没有任何影响。当我们通过引用传递向量时,在那个特定函数中写的是什么,当我们调用那个特定函数时,每个动作都会对在main或其他函数中定义的向量执行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.