重新考虑按值调用与按引用调用

时间:2014-01-20 16:14:36

标签: java c++ function-calls pass-by-reference call-by-value

首先让我说。我知道标题怀疑我问了一个问题,这个问题在这里和互联网上被多次回答。我确实做过研究,但我找不到令人满意的答案。

我的问题最终归结为此。为什么Java Call By Value和C ++ Call By Reference(使用指针时)?

在传递引​​用时考虑使用Java进行方法调用,在传递指针时考虑使用c ++进行方法调用。最后,在这两种情况下,我都能够进行调用者可见的更改。同样在这两种情况下,我都将对象的地址传递给函数。事实上,我正在复制,即在传递指针时,也不是通过c ++中的值进行调用吗?

您可以通过运行以下代码来简单地验证这种情况:

#include <iostream>

void modify (int *i) {
    int a = 5;
    i = &a;
}

int main () {
    int b;
    int *i = &b;
    std::cout << i << std::endl;
    modify(i);
    std::cout << i << std::endl;
    return 0;
}

将打印两次相同的地址。

对我而言,仅通过引用来证明您可以使用它执行交换功能的属性是不够的。我想知道通过引用引用调用的内容的核心。

提前谢谢。

2 个答案:

答案 0 :(得分:1)

  

我的问题最终归结为此。为什么Java Call By Value和C ++ Call By Reference(使用指针时)?

C ++实际上是按值调用,而不是按引用调用。您在C ++中看到的引用行为是您传递指针这一事实的副作用:指针本身是按值复制的。您无法比较这些情况,因为Java没有指针。

答案 1 :(得分:0)

您提供的示例是通过引用不恰当地使用调用。在函数modify

void modify (int *i) {
    int a = 5;
    i = &a;
}

您声明堆栈中的局部变量a。当它超出范围时,其地址毫无意义。因此,将a的地址分配给ii指向的内容没有影响。

因此,通过引用工作调用的是您可以修改函数中i指向的值。例如:

void modify (int *i) {
    int a = 5;
    *i = a;
}

因此在main函数中,您可以将其命名为:

int b = 2;
int *i = &b;
std::cout << *i << std::endl;  //This will print 2
modify(i);
std::cout << *i << std::endl;  //This will prints 5