默认情况下,c ++中的所有内容都按值传递

Cha*_*ara 2 c++ pass-by-reference pass-by-value

在C++中,除非带有&或*符号,否则所有类型都是按值传递的?

例如,在Java中,将数组作为函数参数传递将默认通过引用传递.C++能否为您提供更多控制权?

编辑:感谢您的所有回复,我想我更清楚地了解整个价值传递的事情.对于那些仍然对Java如何通过值传递(对象引用的副本)感到困惑的人,这个答案真的为我清除了它.

gio*_*gim 7

在C++中,除非带有&或*符号,否则所有类型都是按值传递的?

如果你传递的东西为*参数(它的指针),它仍然按值传递.传递指针的副本.但原始和副本都指向同一个内存.它在C#中是类似的概念 - 我也相信在Java中,只是你不使用*.

这就是为什么如果使用此指针对外部对象进行更改(例如使用解除引用),则更改也将在原始对象中可见.

但是如果你只是说为指针分配一个新值,那么外部对象就不会发生任何事情.例如

void foo(int* ptr)
{
  // ...
  // Below, nothing happens to original object to which ptr was 
  // pointing, before function call, just ptr - the copy of original pointer - 
  // now points to a different object 
  ptr = &someObj; 
  // ...
}
Run Code Online (Sandbox Code Playgroud)

例如,在Java中,将数组作为函数参数传递将默认通过引用传递.C++能否为您提供更多控制权?

在C++或C中,如果传递数组(例如int arr[]),传递的内容将被视为指向数组第一个元素的指针.因此,我在上面所说的也适用于这种情况.

关于&你是对的.你甚至可以应用指针(例如int *&),在这种情况下,指针确实通过引用传递 - 没有复制.


Esc*_*alo 5

可能与你的问题无关,但我经常采取另一个方向来理解当你在 C++ 中调用函数时会发生什么。

和...之间的不同

void foo(Bar bar);  // [1]
void foo(Bar& bar); // [2]
void foo(Bar* bar); // [3]
Run Code Online (Sandbox Code Playgroud)

是主体[1]将收到原始栏的副本(我们称其为值,但我更愿意将其视为我自己的副本)。

的主体[2]将使用完全相同的bar对象;没有副本。我们是否可以修改该bar对象取决于参数是Bar& bar(如图所示)还是const Bar& bar。请注意,在格式良好的程序中,[2]将始终接收一个对象(没有null引用;让我们将悬空引用放在一边)。

的主体[3]将收到指向原始 的指针的副本bar。我是否可以修改指针和/或所指向的对象取决于参数是否是const Bar* bar、const Bar* const bar、Bar* const bar或Bar* bar(是的,真的)。指针可能是也可能不是null。

我之所以进行这种心理区分,是因为对象的副本可能具有也可能不具有引用语义。例如:此类实例的副本:

struct Foo {
 std::shared_ptr<FooImpl> m_pimpl; 
};
Run Code Online (Sandbox Code Playgroud)

默认情况下,将具有与原始内容相同的“内容”(指向同一FooImpl指针的新共享指针)。当然,这取决于程序员如何设计类。

出于这个原因,我更喜欢将其视为[1]“获取 bar 的副本”,如果我需要知道这样的副本是否是我想要的以及我需要的,我会直接去学习该类以了解该类的具体内容意思是复制。