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