按值传递与按引用传递内存分配差异 c++

Pass by value vs pass by reference memory allocation difference c++

本文关键字:c++ 分配 内存 按引用传递 按值传递      更新时间:2023-10-16

我想在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引用。这保证不会创建任何副本,并且您不会修改对象。

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