传递常量将通过引用自动传递

本文关键字:引用 常量 | 更新日期: 2023-09-27 18:19:58

如果我将变量传递给函数但将该变量标记为常量,它会自动通过引用传递吗?


在C++

void foo(const int a)

测试后:否,因为它打印不同的内存位置。

void foo(const int a)
{
    cout << &a << endl;
}
int main()
{
   int a = 5;
   foo(a);
   cout << &a << endl;
   return 0;
}

C

没有吧?因为我只能传递指向内存位置的指针,而不是真正的引用。像这里: 在 C 中通过引用传递


爪哇岛

也许编译器可以弄清楚final应该指向相同的内存位置?

void foo(final int a)

C#

和Java一样?

void foo(const int a)


我知道我的问题中包含 4 种语言,但由于我经常使用这 4 种语言,所以我想知道。

有没有办法强制Java和C#来处理这样做?我知道C++我可以向函数添加&,而这正是我想要的。

 void f(const int &a)

这几乎就是我在幕后跳跃的Java和C#编译器正在做的事情。

传递常量将通过引用自动传递

在Java中,所有变量都是按值传递的。

基元实际上是复制的,对象变量

无论如何都是引用,这意味着对象变量的值实际上是引用 ->传递引用的值。

尽管如此,您始终按值传递,与C++中相同,如果不显式使用引用,您将按值传递。

我几乎可以肯定它在 C# 中是相同的。

编辑:我忘记了C

在 C: 默认按值传递中也是如此。显然,你可以传递一个指针。在C++中,这是扩展的,因此您可以将引用作为参数:

void function(int& intByReference) {
    cout<<&intByReference<<endl; //prints x
}
int main() {
    int n = 0;
    cout<<&n<<endl; //prints x
    function(n);
}

由于C++包含类,因此有一个默认构造函数来复制对象:

class MyClass {
    public:
        MyClass(MyClass& objectToCopy) {
            //copy your object here
            //this will be called when you pass an instance of MyClass to a function
        }
};

你错误地认为你的直觉可以指导你如何实现语言的细节。这根本不是真的。在 C++ 和 C 的情况下,规范非常清楚地说明了应该如何处理这个问题。

Java 作为一种按值传递的语言,可能在最终/常量/未触及值的规范中对此行为有一些规定。(我不知道(但只有规范才能允许这种行为。

在回答您的问题之前,让我举例说明一个示例来测试您的方案。

假设您通过传递变量 int a 来调用从方法 void calledFrom() void called(int a )的方法。

据我了解:

如果 a 在任何方法中的值变化影响另一个(a 在calledFrom中的变化会影响 a 在 called 中的值(,那么它通过引用调用,否则它由值调用

现在让我们使用 final 在 java 中测试它

public class MyClass
{
    int a;
    public void setA(final int a)
    {
        this.a=a;
    }
    public void printA()
    {
        System.out.println(a);
    }
}

从主方法中,您可以执行此操作:

int a=10;
MyClass mclass=new MyClass();
mclass.setA(a);
mclass.printA();
a++;
mclass.printA();

输出为:1010

所以在main改变a的值MyClass. 所以对public void setA(final int a)的调用不是通过引用调用,而是按值调用。

关键final可能会引起一些混乱。当你在方法签名中写入 final 时,不会影响任何其他方式的行为except you cant change the value of that parameter inside that method. 例如,如果你写

public void setA(final int a)
{
    a++; //error
    this.a=a;
}

你会得到一个编译错误

但你可以这样做

 public void printA()
{
    a++; //ok
    System.out.println(a);
}

我认为这不仅在java中所有其他语言都有相同的行为。 你可以尝试使用其他语言。

要获得有关在 Java 上下文中按值传递和按引用传递的清晰概念,您可以阅读此线程

或阅读此答案