C++:将数组引用传递给函数是否正常

5

数组可以作为指针传递给函数,甚至可以作为引用传递。将其作为引用传递会得到一个别名,sizeof和count运算符也将在其上工作。这使得按引用传递看起来更加优秀。

然而,在书中,按指针传递似乎是常态。为什么?有没有关于数组按引用传递需要特别了解的事情?

2个回答

5

按引用传递意味着您的函数只能接受固定大小的数组(这就是为什么它知道它们的大小,因为编译器强制执行)。而通过指针传递则不同。此外,通过指针传递可以让您传递 nullptr,好坏参半。


1
动态分配的数组不会被接受为传递引用的参数吗?这是怎么回事?毕竟,引用是一个别名。 - quantum231
动态分配数组已经返回指针,所以不需要。 - Yam Marcovic
1
不需要自动分配,但是存在类型问题。例子:void f(int (&arg)[5]); void g() {f(*new int[1][5]);} - Todd Fleming
@ToddFleming 能否详细说明一下?1. 你在例子中想要表达什么;2. 有哪些情况下可以获得没有自动存储的数组? - Yam Marcovic
这个例子可以编译;传递引用的数组没有自动存储的要求。相反,真正的问题是new返回指向最外层数组的第一个元素的指针;这会丢失一些(而不是全部)大小信息。 - Todd Fleming
哇,没想到那个。谢谢;我会修改的。 - Yam Marcovic

1
我通常使用 std::vector 并喜欢通过 const 引用传递。但是,如果我的 API 可能会被 C 代码调用,则使用通过 const 指针传递可能是有意义的,尽管您还需要发送大小。如果函数可能被调用时使用 std::arraystd::vector,则可以决定发送指针(和大小)或一组迭代器(begin/end)。
如果我们谈论使用 std::array,模板参数需要数组的大小。这意味着在普通函数中,您需要一个固定的大小:
void myfunc( const std::array<int, 5>& mydata ){...}

然而,如果我们使用模板函数,在大小上进行模板化,那么这将不再是一个问题。
template<unsigned int SZ>
void myfunc(const std::array<int, SZ>& mydata) {...}

如果我们谈论堆栈分配的C风格数组... 好的C++风格是优先使用std::array/std::vector而不是C风格数组。我建议阅读Herb Sutter的C++编程规范第77章,第152页讨论这个主题。在使用C风格数组时,将指针和大小发送下去是标准做法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接