将 Java 的按值传递与C++的按值传递或引用进行比较

Comparing Java's pass-by-value with C++'s pass-by-value or -reference

本文关键字:按值传递 比较 引用 C++ Java      更新时间:2023-10-16

Java使用传递值,同时使用对象和基元类型。因为Java传递引用的值,所以我们可以更改target的值,但不能更改地址。

这与C++相比如何?

区别在于是否可以影响调用函数中的变量。

让我们暂时把物体放在一边。在纯按值传递的Java中,不能更改传递到被调用函数中的变量的调用函数的值。示例:

void foo() {
int a = 42;
bar(a);
System.out.println("foo says: " + a);
}
void bar(int a) {
a = 67;
System.out.println("bar says: " + a);
}

如果你打电话给foo,你会看到:

酒吧说:67foo说:42

bar无法更改fooa

在C++中,如果您传递值,则情况也是如此。但是,如果您通过引用,则将参考传递给调用代码的变量。这意味着被调用的代码可以改变它:

void foo() {
int a = 42;
bar(a);
cout << "foo says: " << a;
}
void bar(int& a) {
a = 67;
cout << "bar says: " << a;
}

注意,bar被定义为接收引用(int& a)。如果你打电话给bar,你会看到:

酒吧说:67foo说:67

bar能够在foo内更改a

好吧,让我们来处理对象引用:首先,请注意,"引用"一词用于两个完全不同的东西:对调用函数中的变量reference(这是通过引用的东西),以及对对象reference。当您将对象引用传递到Java中的方法中时,该引用将通过传递,就像其他一切一样。

void foo() {
List list = new ArrayList();
List ref2 = list; // (Let's remember that object reference for later...)
bar(list);
System.out.println("foo says: " + list.size());
System.out.println("foo says: Same list? " + (ref2 == list));
}
void bar(List list) {
// `bar` can modify the state of the object the reference points to
list.add(new Object());
System.out.println("bar says (after add): " + list.size());
// ...but cannot change `foo`'s copy of `list`
list = new ArrayList();
System.out.println("bar says (after new): " + list.size());
}

所以你看到了:

酒吧说(添加后):1酒吧说(在新的之后):0傅说:1傅说:同样的名单?true

bar可以更改其引用(按值)传入的对象的状态,但不能更改foo对该对象的引用。foo没有看到创建的新列表bar

在Java中,您可以通过值传递基元和引用。没有其他选择。

在C++中,可以通过值或引用传递基元和指针。如果通过引用传递,则可以看到在将值或指针传递给方法后对其所做的更改,并且可以更改原始值。

区别在于是否可以影响调用函数中的变量。

让我们暂时把物体放在一边。在纯按值传递的Java中,不能更改传递到被调用函数中的变量的调用函数值。示例:

void foo() {
int a = 42;
bar(a);
System.out.println("foo says: " + a);
}
void bar(int a) {
a = 67;
System.out.println("bar says: " + a);
}

如果你调用foo,你会看到:

酒吧说:67傅说:42酒吧无法更改foo的a.

在C++中,如果您传递值,则情况也是如此。但是,如果通过引用传递,则传递对调用代码的变量的引用。这意味着被调用的代码可以改变它:

在C++中,与Java等价的东西就是这个

void Swap(Type* A, Type* B)
{
// here we have pointers to type A (in Java they are called references and don't use * syntax)
A->DoThis() // can call with -> a method on object
//if you try to swap A with B not possible because we don't have A*/B* reference
// see bellow how to do this
}

在C++中处理上述限制的方法是

void Swap(Type& A, Type& B)
{
Type& temp = A;
A = B;
B = temp;
}