当前位置: 首页 > 面试题库 >

Java和C ++按值传递并按引用传递

汪深
2023-03-14
问题内容

据说在Java方法中,参数是通过值传递的,这对于基元和对象都是正确的,而对象的引用是通过值传递的。为了说明,请考虑以下代码:

class Test {
 private static void dateReplace (Date arg) {
        arg = new Date (arg.getYear(), arg.getMonth(), arg.getDate() +1);
        System.out.println ("arg in dateReplace: " + arg);
    }

 public static void main(String[] args) {

      Date d1 = new Date ("1 Apr 2010");
        dateReplace(d1);
        System.out.println ("d1 after calling dateReplace: " + d1);
    }
}

this will print:
arg in dateReplace: Fri Apr 02 00:00:00 2010
d1 after calling dateReplace: Thu Apr 01 00:00:00 2010.

能给出相同结果的C ++等价物是什么?

在调用该方法后,使d1的值与该方法内的值相同,即调用方看到修改后的值,那么C ++的等效项是什么?


问题答案:

C ++对于值和引用的语义与Java不同。首先,每种类型都有可能通过复制,引用或地址传递(但是,可以通过隐藏复制构造函数来防止通过复制传递类型)。

与Java的“按引用”传递最紧密相关的传递类型是按指针。这是三个示例:

void foo(std::string bar); // by copy
void foo(std::string& bar); // by reference
void foo(std::string* bar); // by address

附带说明一下,对于大于指针大小的类型,通过副本传递总是比通过引用或指针传递更昂贵。出于这个原因,您可能通常也更喜欢通过const引用传递,这将使您无需复制即可读取对象。

void foo(const std::string& bar); // by const reference

但是,这都是棘手的问题,您需要了解Java的精妙之处,才能正确决定C
的要求。在Java中,实际上并没有通过引用传递对象:而是通过副本传递对象引用。也就是说,如果将新对象分配给参数,则父作用域的对象不会更改。在C

中,这与通过地址而不是通过引用更紧密地匹配传递的对象。这是一个重要的示例:

// Java using "object references":
public static void foo(String bar)
{
    bar = "hello world";
}

public static void main(String[] argv)
{
    String bar = "goodbye world";
    foo(bar);
    System.out.println(bar); // prints "goodbye world"
}

// C++ using "references":
void foo(std::string& bar)
{
    bar = "hello world";
}

int main()
{
    std::string bar = "goodbye world";
    foo(bar);
    std::cout << bar << std::endl; // prints "hello world"
}

// C++ using pointers:
void foo(std::string* bar)
{
    bar = new std::string("goodbye world");
    delete bar; // you don't want to leak
}

int main()
{
    std::string bar = "goodbye world";
    foo(&bar);
    std::cout << bar << std::endl; // prints "hello world"
}

换句话说,当您在C 中使用引用时,实际上是在处理传递的 相同变量 。您对其所做的任何更改,甚至是分配,都将反映到父范围。(部分原因是C

如何处理赋值运算符。)使用指针,您得到的行为与Java引用的行为更紧密相关,但代价是必须通过一元运算&符获取对象地址(请参见foo(&bar)在我的示例中),需要使用->运算符来访问成员,并且使用运算符重载会带来一些额外的复杂性。

另一个显着区别是,由于按引用自变量的用法在语法上与按副本自变量的用法紧密相关,因此函数应能够假定您通过引用传递的对象是有效的。即使通常可以传递对的引用NULL,也强烈建议不要这样做,因为这样做的唯一方法是取消引用NULL,这具有不确定的行为。因此,如果您需要能够NULL作为参数传递,则更希望通过地址传递参数,而不是通过引用传递参数。

大多数情况下,当您要修改函数中的参数时,您希望通过引用而不是地址进行传递,因为它更“ C ++友好”(除非您需要该NULL值),即使它不完全像Java。



 类似资料:
  • 问题内容: 我一直认为Java使用传递引用。 但是,我已经看到了几篇博客文章声称不是(博客文章说Java使用值传递)。 我不认为我能理解他们的区别。 有什么解释? 问题答案: Java总是按值传递。 不幸的是,我们根本不处理任何对象,而是处理称为引用的 对象句柄(当然是通过值传递)。选择的术语和语义很容易使许多初学者感到困惑。 它是这样的: 在上面的示例中仍将返回”Max”。值aDog内main未

  • 问题内容: 我读了许多文章,都说Java是通过价值传递的。但是我仍然不能解释按值传递和引用之间的区别。我写了一个示例程序,它像这样执行。 执行 谁能向我解释这些问题… 价值传递是什么意思? 答:它只是将存储在变量中的数字或值传递给函数。我是对还是错。 How do you say Java是通过价值传递? 为什么Java是按值传递而不是按引用传递? 上面的程序Tries是否显示了“按值传递”和“引

  • 两者之间有什么区别 引用传递的参数 通过值传递的参数? 你能给我举几个例子吗?

  • 本文向大家介绍JS是按值传递还是按引用传递,包括了JS是按值传递还是按引用传递的使用技巧和注意事项,需要的朋友参考一下 按值传递 VS. 按引用传递 按值传递(call by value)是最常用的求值策略:函数的形参是被调用时所传实参的副本。修改形参的值并不会影响实参。   按引用传递(call by reference)时,函数的形参接收实参的隐式引用,而不再是副本。这意味着函数形参的值如果被

  • 本文向大家介绍什么是PHP中的按引用传递和按值传递?,包括了什么是PHP中的按引用传递和按值传递?的使用技巧和注意事项,需要的朋友参考一下 在本文中,我们将学习PHP中的按值传递和按引用传递。  现在,让我们详细了解这两个概念。 通常,在PHP中,我们遵循通过按值传递方法将参数传递给函数的方法。我们之所以遵循这种做法,是因为如果函数中参数的值被更改,则在函数外部它不会被更改。 在某些情况下,我们可

  • 问题内容: 基本类型(数字,字符串等)按值传递,但对象未知,因为它们都可以按值传递(如果我们认为保存对象的变量实际上是对该对象的引用) )和按引用传递(当我们认为对象的变量包含对象本身时)。 尽管最后并没有什么大不了,但我想知道呈现通过惯例的参数的正确方法是什么。是否有JavaScript规范的摘录,其中定义了与此相关的语义? 问题答案: JavaScript很有趣。考虑以下示例: 产生输出: 如