【问题标题】:Pass by value vs pass by reference memory allocation difference c++按值传递与按引用传递内存分配差异c ++
【发布时间】:2013-09-24 23:01:08
【问题描述】:

我想将一个巨大的 stl 向量传递给 C++ 中的函数,当我按值传递时,它是否会在内部复制巨大的向量?我不清楚按值传递和按引用传递在内存分配方面有何不同。引用传递是否更节省内存?我应该只将那个巨大向量的指针传递给函数,以便节省大量内存吗?

有人可以向我解释以下三种情况在记忆方面的差异吗? 假设 obj 很大。

1. func(vector<obj> )

2. func(vector<obj>*) 

3. func(vector<obj*>)

【问题讨论】:

标签: c++ memory


【解决方案1】:

您的第三个选项与前两个完全不同。类型不同。我将讨论前两个选项(并介绍更多选项)。

func(vector&lt;obj&gt; ) - 传值

内部所做的更改不会反映在外部。理论上,复制是有的。但是,语义是不同的。你不能通过价值传递并实现同样的目标。此外,对于 C++11 中的移动语义,值传递和引用传递行为相同的情况具有相同的效率,因为向量不是复制的,而是 移动的.

func(vector&lt;obj&gt;*) - 按值传递指针

制作了指针的副本。在内部,指针本身的更改不会反映在外部。它指向的vector 的更改是。所以效果与之前的选项不同——如果你想做出没有反映在外面的改变,你无论如何都需要一份副本。

func(/*const*/ vector&lt;obj&gt;&amp;) - 通过引用传递

如果不是const,则更改会反映在外部。同样,不同的语义 - 如果您正在修改对象,更改将反映在外部。如果你不想要那个(变化反映在外面),你还是需要一份副本。

三者之间的决定并非易事。

第二个更接近你在 C 中所做的,所以如果可以的话,我会避免它(不需要 + 你可以通过引用传递实现相同的效果 + 没有裸指针)。

如果您想修改函数内部的对象并将更改反映在外部,请使用非const 引用传递。无论如何,这无法通过按值传递来实现。

如果您不打算修改对象,请使用 pass by const 参考。这保证不会复制,并且您不会修改对象。

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

【讨论】:

  • +1 很好的答案,比我的要好得多。我不太了解这种移动条件。
  • 非常感谢您的详细回答。我想要的其实是你的最后一段,修改里面的对象而不是外面的。但我买不起矢量的副本,它太大了。你能在move semantic 上解释更多吗?它是如何使用的,我必须明确写出我想要移动而不是复制吗?
  • @LoganYang 你怎么能修改 same 对象而不改变外部。你需要一份副本,对吧?
  • 那么外面的变化就可以了,我只需要之后重置它们。我的首要任务是避免复制巨大的矢量
  • @LuchianGrigore 抱歉,我仍然不清楚您在 按值传递 下写的内容。我用-std=c++11 编译并按值将向量传递给函数是真的吗,它不会复制但确实会移动?有没有副本?
猜你喜欢
  • 2013-08-05
  • 2023-03-02
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
  • 2016-10-22
相关资源
最近更新 更多