我想将一个巨大的 stl 向量传递给 C++ 中的函数,当我按值传递时,它是否会在内部复制巨大的向量?我不清楚按值传递和按引用传递在内存分配方面有何不同。引用传递是否更节省内存?我应该只将那个巨大向量的指针传递给函数,以便节省大量内存吗?
有人可以向我解释以下三种情况在记忆方面的差异吗?假设 obj 很大。
1. func(vector<obj> )
2. func(vector<obj>*)
3. func(vector<obj*>)
您的第三个选项与前两个完全不同。类型不同。我将讨论前两个选项(并提供更多选项)。
func(vector<obj> )
-按值传递
内部所做的更改不会反映在外部。理论上,复制是有的。但是,语义不同。你不能通过价值传递并实现同样的目标。此外,使用 C++11 中的移动语义,值传递和引用传递行为相同的情况具有相同的效率,因为向量不是复制的,而是移动的。
func(vector<obj>*)
-按值传递指针
制作了指针的副本。在内部,指针本身的更改不会反映在外部。vector
它指向的变化是。所以效果与之前的选项不同——如果你想做出没有反映在外面的改变,你无论如何都需要一份副本。
func(/*const*/ vector<obj>&)
-通过引用传递
如果没有const
,变化就会反映在外部。同样,不同的语义 - 如果您正在修改对象,更改将反映在外部。如果您不希望这样(更改反映在外部),则无论如何您都需要一份副本。
第二个更接近你在 C 中所做的,所以如果可以的话,我会避免它(不需要 + 你可以通过引用传递 + 没有裸指针来实现相同的效果)。
如果要修改函数内部的对象并将更改反映在外部,请使用非const
引用传递。无论如何,这无法通过按值传递来实现。
如果您不打算修改对象,请使用按const
引用传递。这保证不会复制,并且您不会修改对象。
如果要修改对象但不让更改反映在外部,请使用按值传递。在更改不会反映在外部的情况下,避免复制(即当您传递临时文件时)并且首选移动。在他们愿意的情况下,无论如何您都需要原始对象的副本。