1

我想将一个巨大的 stl 向量传递给 C++ 中的函数,当我按值传递时,它是否会在内部复制巨大的向量?我不清楚按值传递和按引用传递在内存分配方面有何不同。引用传递是否更节省内存?我应该只将那个巨大向量的指针传递给函数,以便节省大量内存吗?

有人可以向我解释以下三种情况在记忆方面的差异吗?假设 obj 很大。

1. func(vector<obj> )

2. func(vector<obj>*) 

3. func(vector<obj*>)
4

1 回答 1

8

您的第三个选项与前两个完全不同。类型不同。我将讨论前两个选项(并提供更多选项)。

func(vector<obj> )-按值传递

内部所做的更改不会反映在外部。理论上,复制是有的。但是,语义不同。你不能通过价值传递并实现同样的目标。此外,使用 C++11 中的移动语义,值传递和引用传递行为相同的情况具有相同的效率,因为向量不是复制的,而是移动的。

func(vector<obj>*) -按值传递指针

制作了指针的副本。在内部,指针本身的更改不会反映在外部。vector它指向的变化是。所以效果与之前的选项不同——如果你想做出没有反映在外面的改变,你无论如何都需要一份副本。

func(/*const*/ vector<obj>&) -通过引用传递

如果没有const,变化就会反映在外部。同样,不同的语义 - 如果您正在修改对象,更改将反映在外部。如果您不希望这样(更改反映在外部),则无论如何您都需要一份副本。

三人之间的决定并非易事。

第二个更接近你在 C 中所做的,所以如果可以的话,我会避免它(不需要 + 你可以通过引用传递 + 没有裸指针来实现相同的效果)。

如果要修改函数内部的对象并将更改反映在外部,请使用非const引用传递。无论如何,这无法通过按值传递来实现。

如果您不打算修改对象,请使用按const引用传递。这保证不会复制,并且您不会修改对象。

如果要修改对象但不让更改反映在外部,请使用按值传递。在更改不会反映在外部的情况下,避免复制(即当您传递临时文件时)并且首选移动。在他们愿意的情况下,无论如何您都需要原始对象的副本。

于 2013-09-24T23:15:35.760 回答