按值传递与按引用传递内存分配差异 c++
Pass by value vs pass by reference memory allocation difference c++
我想在C++中将一个巨大的 stl 向量传递到函数中,当我按值传递时,它会在内部复制巨大的向量吗?我不清楚按值传递和按引用传递在内存分配方面有何不同。按引用传递是否更节省内存?我是否应该只将那个巨大矢量的指针传递到函数中,以便节省大量内存?
有人可以向我解释以下三种情况在记忆方面的差异吗?假设 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
引用。这保证不会创建任何副本,并且您不会修改对象。
如果要修改对象,但不将更改反映在外部,请使用按值传递。在更改不会反映在外部的情况下,会避免复制(即当您传递临时副本时(,并且首选移动。在这种情况下,无论如何您都需要原始对象的副本。
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 在c++中使用动态分配的问题
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 为什么我可以使用比分配的内存更多的内存
- 使用RAII在给定次数的迭代后重新分配资源