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