4

这个问题很简单,之前可能已经讨论过,但我可以为我的案例找到一个明确的答案。假设我将指针对象传递给函数

#include "foo.h"
int main()
{
   foo * aFoo = new foo;
   bar(aFoo);
   delete aFoo;
   aFoo = NULL;
   return 0;
}

然后函数是这样写的

void bar (foo *f)
{
  f->insert();
}

问题:

那是一个call by value还是call by reference?我知道在按值调用中,将对象从 main() 复制到 bar() 会产生开销。所以我想确定这是一个call by reference.

4

2 回答 2

11

它是按值调用,其中指针 aFoo的值被复制到函数参数f中。

引用调用是参数为引用的调用,当函数返回时,调用者可以看到函数内部发生的参数(而不是该参数可能指向的对象)的副作用。

例如,这是一个通过引用接受参数的函数:

void bar(foo*& f)
//           ^
//           Here you are taking a pointer by reference

虽然这是一个按值接受参数的函数:

void bar(foo* f)
//          ^
//          Here you are taking a pointer to foo by value

您可能对以下事实感到困惑:foo通过引用和写作:

void bar(foo& f)
{
    f.insert();
}

与通过值传递指向同一foo对象的指针并写入几乎相同的效果:

void bar(foo* f)
{ // Precondition: f != nullptr
    f->insert();
}

然而,这两件事在概念上是不同的。虽然当函数从调用函数之前的值/状态返回时,您在第一种情况下传递的对象的值/状态可能会有所不同,但在第二种情况下,您提供的指针的值将与它相同在你打电话之前bar()- 而指向的对象可能已经发生了一些状态变化。

另请注意,指针可以为空,而引用始终绑定到对象。

于 2013-06-13T17:40:39.147 回答
1

在您的情况下,它是call by value正式指向 Foo 的指针。但是由于您将指针传递给函数而不是类实例本身,因此它在概念上是通过引用来调用类实例,因为函数调用不会复制整个实例,而只是复制其指针。

Foo fooInstance;
// providing a way to point (less formally you can call it refer) to the instance
Foo* fooPointer = &fooInstance;

// this function call is call by value (passing the value of the pointer).
// but you can logically view it as 'call by reference' to fooInstance.
bar(fooPointer); 
于 2013-06-13T18:01:14.183 回答