C++ References and Java References

后端 未结 4 1503
忘了有多久
忘了有多久 2020-12-30 08:06

//C++ Example

#include 
using namespace std;

int doHello (std::string&);
int main() {
    std::string str1 = \"perry\";
    cout <<         


        
4条回答
  •  时光说笑
    2020-12-30 08:20

    Parameter passing, call-by-reference and call-by-value (short answer)

    In C++ there are two parameter passing forms, call by value and call by reference. (The better name for call-by-value is call-by-new-L-value, but I digress.)

    In Java programs all parameters are passed by value. [There are some people that think that Java passes objects by reference, but they're wrong—see the long answer below—Java passes the reference value of Objects, but that is not the same thing at all.]

    The value of a Java Object (and what is passed) is a pointer to the object (confusingly, but accurately, called a reference to the object), and calling a Java object method, for example, obj.meth(), de-references the pointer value of obj before calling the method on the object found there.

    In C++ the same call would look like: obj->meth().

    If you manipulate the object (for example, by calling a method on it) passed as a parameter to a method in Java, this may modify the object, and if the caller still has a variable holding that object it can see these changes. If you merely assign to the (local) parameter variable, you simply update the pointer stored in the local variable—the object is unaffected, and the caller will not notice this.

    So, the short answer to your question is that Java passes by value, and the call-by-reference mechanism of C++ is not available in Java.

    Parameters, variables and call-by-value (long answer)

    To understand what's going on here we need to understand the mechanics of variables and parameter passing a bit more.

    Variables

    Generally speaking, a variable in a programming language is an identifier that is associated with a value. Variables that denote values manipulated at runtime (we are here ignoring macro variables, constants that are 'compiled away', and so forth) have to have two values associated with them. Here is an example that explains why:

    int a = 0;
    a = a + 1;
    

    a is the variable, and in the line a = a + 1; it is referred to twice. Once, (on the right hand side of the =) the value 0 is meant and once, (on the left hand side of the =) the location of the value of a is meant (that is, where the integer value of a is stored). Only by accessing the location can the program update the value which is contained in it.

    These two values associated with a variable are called the R-value and the L-value. (These names were invented by Christopher Strachey; I'm a fan.) Other constructs in the language refer to one or other of these values depending upon context. For example:

    a[x-1] = x;
    

    refers to the R-value of x twice (even though one is on the left-hand-side of the =), but only the L-value of a (or at least one of the elements of the array a).

    In most programming languages, we explicitly manipulate the R-values of variables, and leave the compiler (from the form of the program) to manage the L-values automatically for us. We have to understand them a bit (in C, in particular with arrays, we assume a lot about L-values), but most of the time we don't have to know the mechanics.

    Call by value

    Look at this call:

    int p=1;
    obj.meth(p);
    …
    void meth(int a) {…a…}
    

    What happens to the parameters here? First the R-value of p is calculated, then, when meth is 'entered', a new variable a is constructed. It is given a new L-value (this location is normally on a stack of some sort) and the R-value of the parameter is stored in the location.

    Now, when a appears in meth it has the same R-value that p had (initially) and a new L-value. Changes to a's R-value make no difference to the variable p. This is called call-by-value (more properly, call-by-new-L-value).

    Call by reference

    Look at this C++ call:

    int p=1;
    obj.meth(p);
    …
    void meth(int& a) {…a…}
    

    Here the L-value of the parameter p is calculated, and when the variable a is constructed it is “given” the same L-value as p. Then any use of a in the body of meth is just like a use of p. Assignment, for example will alter the stored value in p as well as (apparently) the value in a.

    Java doesn't do this.

提交回复
热议问题