Methods and Parameter Java to C++
This example code shows the various ways in which values can be passed to methods and returned from methods in C++. There are more options in C++ than in Java. To duplicate Java behavior, always use pointers to objects as shown in some of the code below.

Java

C++






*Something.java[2] means the file "Something.java" at line 2.

Parameter passing in C++

When calling a method in Java there are only two ways that parameters are passed. For passing a simple value such as an int or float the techique is called pass by value. That is where the value supplied in the argument is copied into the parameter. For objects (anything that has a class) parameter passing is always pass by pointer. A pointer to the object is copied into the parameter. This mirrors the fact that all object variables are actually pointers to objects rather than the actual objects themselves. The reason for passing pointers to objects is that recopying the objects every time they are passed is very expensive.

In C++ there are three basic types of parameter passing. Pass by value is the normal technique which copies the argument into the parameter. A programmer may also select pass by pointer or pass by reference. Examples of these are shown below. The important differences arise when passing objects.

Main in Java

In Main.java[3-6,11] there are five object variables declared of class APoint. All of them are actually pointers to the objects as show in the figure below.

Main in C++

The C++ code creates its variables differently to show the various ways in which values can be used with methods in C++. A Main.cpp[6-7] the variables a and b are declared to just be on the stack as shown in the figure below. There is no pointer involved. The declaration does not use new as Java does. The variable c at Main.cpp[8] is declared as pointer (with the *) and receives its value from a new. Note that it appears as a pointer in the figure below, the same as in Java. Variable d at Main.cpp[9] is on the stack and variable e at Main.cpp[16] is declared as a variable. We will use these variables with our methods to show how the parameters are passed.

Passing a whole object

In our first example we will call the makeSameAs method from Main.cpp[18]. The makeSameAs method is declared at APoint.cpp[24-28]. Note that makeSameAs has a single parameter called other which is of class APoint. There are no other modifiers on the parameter other so it is passed by value. The contents of the variable a in Main.cpp[18] are copied into the parameter other. This is shown in the figure below. In the case of a simple class like APoint there are only three values to copy. In a class with many fields, this copying would be very expensive.

Passing a pointer to an object

The method distanceTo at APoint.cpp[17-23] uses a different technique. As you can see the parameter other for this method is declared as a pointer (note the *) to APoint rather than the APoint object itself. When this method is called at Main.cpp[14] it is passed the variable c as an argument. The variable c is itself a pointer. The calling stack works as shown in the figure below. Note that no matter how many fields the object has, only the single pointer value must be copied when passing parameters this way. This is much more efficient, which is why Java always does it this way. For former Java programmers, this is the recommended way to pass objects as parameters.

Because the parameter other is a pointer we must use the arrow notation rather than the dot to access fields as shown at APoint.cpp[19-20].

Passing a reference to an object

Because of the efficiency of passing a pointer rather than an object C++ has a syntax for passing a pointer while treating the parameter as if it was the object itself. This hides the pointer while retaining the efficiency of Java's approach. The method diff at APoint.cpp[33-37] is an example of this. Note that this time the parameter other is declared with an &. This & indicates passing by reference. Passing by reference masquerades as a variable while actually passing a pointer. At Main.cpp[16] the variable d is not a pointer. It is just a variable of class APoint. However, because other is now declared to pass by reference, a pointer to d is passed rather than copying all of d. This has the same efficiency as passing a pointer. Note in the method diff that the fields of other are accessed by dot notation rather than arrow notation. This is because pass by reference is hiding the existance of the pointer.

Returning a whole object

Up until now we have ignored the values that are returned by methods. However, return values have the same issues as parameters. When we specify that a method will return a value, it reserves space for that value on the stack the same as for parameters. If we return a whole object then space must be reserved for a whole object. In the origin method at APoint.cpp[29-32] the return type is APoint. At APoint.cpp[30] we create a point with [0,0,0] and store it in the variable result. When the return is performed at APoint.cpp[31] the value of result is copied into the return value. After the method returns, the return value is copied into the variable that is to receive the result. This is a double copy and very expensive. It is even more expensive with very large objects.

Returning a pointer to an object

The method diff at APoint.cpp[33-37] returns a pointer to its result. This is much cheaper because only the single value of the pointer is copies rather than the whole object. This is the technique that Java uses automatically.

Virtual methods

In Java there is only one way to override inherited methods. However, in C++ there are two ways. For Java programmers the preferred mechanism is to declare every method as virtual. This is shown at APoint.h[11-15]. Declaring the methods virtual will cause inheritance to work exactly the same as Java.

ostringstream

In this example code we declared a toString method at APoint.java[11-12]. In this method we used the rather simple + operator to concatonate pieces of string together to form the return value. This simple mechanism is not available in C++. In the toString method at APoint.cpp[12-16] we have used the ostringstream class to perform the same task. To use this class you must include the iostream and sstream headers as shown at APoint.cpp[3-5].

This class creates an output stream (as in writing to a file or the console) except that in this case all of the writing is done to a string in memory. Note that APoint.cpp[14] is performing the same function as APoint.java[12] only using a different technique. However, the variable rslt is not a string, it is an ostringstream. To get its string one must use its str() method as shown at APoint.cpp[15].