6

Ive started to get my head in a bit of a mix regarding how Java and C++ pass arguments.

Is this correct:

Java passes using call by value, but the value is actually the reference (not the actual data/object). So a copy of the address is made?

C++ by default, passes by value, but the value is not the reference, its the actual data. If you want to simular real call by reference use & or a pointer?

In summary, Java makes copies of parameters, but it's a copy of the reference. C++ usually makes a copy but not of the reference (unless you use & or pointers), of the actual underlying data?

Luca Geretti
  • 10,206
  • 7
  • 48
  • 58
intrigued_66
  • 16,082
  • 51
  • 118
  • 189
  • 2
    Minus 1....... for asking a genuine question? Dear dear...... and no comment as to why! – intrigued_66 Jun 20 '12 at 15:37
  • 1
    Actually, you asked two questions that are completely independent of one another: "Is this how Java passes arguments?" and "Is this how C++ passes arguments?" They're both yes/no questions, which means they're not very interesting; they'd be better posted separately and phrased as "What parameter-passing style does *X* use?" But then they're both surely answered here already; did you search first? – Rob Kennedy Jun 20 '12 at 15:48

5 Answers5

3

C++(03) always makes a copy unless you pass by reference. (Theoretically... in practice, copy elision can occur, but it's irrelevant in regards to the question)

If you pass by pointer, you still make a copy (granted, it's a copy of the pointer, but still a copy).

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • *C++ always makes a copy*.. or move. – Nawaz Jun 20 '12 at 15:32
  • 1
    "copy elision can occur, but the observed behavior is the same" - unless the copy constructor has observable side-effects, in which case the observable behavior is not the same. But for most types, the copy either has no observable side-effects, or the effects aren't usually observed (e.g. memory allocation). – Steve Jessop Jun 20 '12 at 15:34
  • 1
    @Porcupine: C++11 supports move-semantics also, so the function argument(s) could be formed as a result of move operation, rather than copy operation. So if it is formed as a result of move-operation, we may call it *moved* object, rather than *copied* object. – Nawaz Jun 20 '12 at 15:37
  • 2
    @SteveJessop: The standard explicitly allows this change of behavior. The responsibility is passed to the programmer: *you shall not depend on side effects of copy construction as it might be elided under some circumstances...* – David Rodríguez - dribeas Jun 20 '12 at 15:43
2

Your summary is correct.

I personally find simpler, when comparing Java with C++, to consider Java as the equivalent of C++ when non-primitive types are passed as pointers by value. In Java you just do not see, and cannot manipulate, the pointer.

Luca Geretti
  • 10,206
  • 7
  • 48
  • 58
1

The summary for Java is correct. Indeed, it also applies to non-reference types.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

Well, in both Java and C++, there are two options when passing arguments: Pass by Value(PbV) and Pass by Reference(PbR). Java pass all preliminary objects by value, and pass all other objects by reference. While C++ pass everything by value unless you require to pass by reference.

  1. Pass by Value

In both Java and C++, pass by value is to make a copy of the passed object, what you do in the function to the object will not have any influence on the original object outside the function. e.g.,

void foo(aTemp)
{
aTemp = 2;
}
....
int a = 1;
foo(a)
std::cout << a;

The output will be 1;

  1. Pass by Reference

Pass by reference does not make a copy of the object, it makes a copy of the reference of the object. e.g.

void foo(&aTemp)
{
aTemp = 2;
}
....
int a = 1;
foo(a)
std::cout << a;

The output will be 2.

  1. More Complicated Situation

So far, there is no big difference between java and c++. However, if you assign passed-in object to a new one, the situation will be different. e.g. in C++,

 void foo(&aTemp)
 {
 myClass b(2);
 aTemp = b;
 }
 ...    
 myClass a(1);
 foo(a)
 std::cout << a;

The output will be 2.

However, in Java

void foo(aTemp)
{
myClass b = new myClass(2);
aTemp = b;
}
...
myClass a = new myClass(1);
foo(a)
std::cout << a;

The out put will be 1.

The different output here is caused by the difference in "=" in java and c++.

In c++, if you do not override "=" in a irregular way, the value of myClass b will be copied into aTemp which points to a.

While in Java, when you do aTemp = b, you assign the address of object b to aTemp, so aTemp no longer points to the original a, and no matter what you do to aTemp, it has no long influence on a.

So in summary, all arguments in Java and C++ are passed by value -- value of the object or value of the reference -- the difference only lays on how you manipulate the value.

This is what I learned from my normal work, hope this helps.

Kun
  • 21
  • 2
0

That is correct. Please note also that Java actually does make a copy for primitive types (int, char, double, float, short, long, boolean, and byte), though not arrays of primitive types (int[], char[], and the like are still passed by reference) or wrapper classes (such as Integer and Double, which are objects that contain primitive types). You can do anything you want to the local copy of an argument inside a function if it's a primitive type and the calling function's copy of the argument will remain unchanged.

algorowara
  • 1,700
  • 1
  • 15
  • 15
  • 2
    primitive arrays are not passed by reference. Nothing is ever passed by reference in Java. Arrays of primitives are reference types, they are not primitive types, so, just like any other class, you are passing a pointer (or reference, if you prefer) by **value**. – Servy Jun 20 '12 at 16:24