Cha*_*ara 2 c++ pass-by-reference pass-by-value
在C++中,除非带有&或*符号,否则所有类型都是按值传递的?
例如,在Java中,将数组作为函数参数传递将默认通过引用传递.C++能否为您提供更多控制权?
编辑:感谢您的所有回复,我想我更清楚地了解整个价值传递的事情.对于那些仍然对Java如何通过值传递(对象引用的副本)感到困惑的人,这个答案真的为我清除了它.
在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 *&),在这种情况下,指针确实通过引用传递 - 没有复制.
可能与你的问题无关,但我经常采取另一个方向来理解当你在 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 的副本”,如果我需要知道这样的副本是否是我想要的以及我需要的,我会直接去学习该类以了解该类的具体内容意思是复制。