C++ passes by reference, Java and Ruby don’t
I got a lot of comments for the previous article, that was explaining how Ruby passes by value, just like Java does.
I thought that showing a simple example implemented in C++, Java and Ruby will clarify the idea. In the following lines, we will make swap functionality in 3 languages, and demonstrate that neither Java nor Ruby passes by reference.
C++
#include <iostream>
using namespace std;
class Point {
private:
double x, y;
public:
Point(double x, double y) {
this->x = x;
this->y = y;
}
void print() {
cout << "x = " << x << ", y = " << y << endl;
}
};
// Parameters are passed by reference
void swap(Point &p1, Point &p2) {
Point temp = p1;
p1 = p2;
p2 = temp;
}
int main() {
//initializing the points
Point val1(5, 10);
Point val2(20, 40);
//printing their values
cout << "Before Passing By Reference" << endl; val1.print(); val2.print();
//swaping, passing by referecne
swap(val1, val2);
//printing the values again
cout << "After Passing By Reference" << endl; val1.print(); val2.print();
}
</iostream>
Output:
$ ./passcpp
Before Passing By Reference
x = 5, y = 10
x = 20, y = 40
After Passing By Reference
x = 20, y = 40
x = 5, y = 10
Java
class Point {
private double x, y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public String toString() {
return String.format("x = %.2f , y = %.2f", x, y);
}
public static void swap(Point p1,Point p2){
Point temp = p1;
p1 = p2;
p2 = temp;
}
public static void main(String args[]) {
//initializing the points
Point var1 = new Point(5, 10);
Point var2 = new Point(20, 40);
//printing their values
System.out.printf("Before Passing\n%s\n%s\n", var1, var2);
// //swaping, passing by reference value, aka: pass by value
swap(var1,var2);
//printing the values again
System.out.printf("After Passing\n%s\n%s\n", var1, var2);
}
}
Output:
$ java Point
Before Passing By Reference
x = 5.00 , y = 10.00
x = 20.00 , y = 40.00
After Passing By Reference
x = 5.00 , y = 10.00
x = 20.00 , y = 40.00
Ruby
class Point
def initialize(x,y)
@x,@y = x,y
end
def to_s
"x = #{@x} , y = #{@y}"
end
end
def swap(p1,p2)
p1,p2 = p2,p1
end
#initializing the points
var1 = Point.new(5,10)
var2 = Point.new(20,40)
#printing their values
puts "Before Passing" , var1, var2
# //swaping, passing by reference value, aka: pass by value
swap var1,var2
#printing the values again
puts "After Passing" , var1, var2
Output:
$ ruby passruby.rb
Before Passing By Reference
x = 5 , y = 10
x = 20 , y = 40
After Passing By Reference
x = 5 , y = 10
x = 20 , y = 40
As you can notice, in c++ example, passing by reference, will do the swap successfully.
Java and Ruby both don't pass by reference, instead they pass a copy of the reference, which is a value finally, and so the swap fails, as swapping the copies doesn't swap the original passed objects.
Please note also that in Java, primitive types are passed by their values directly and no need for any kind of references copies.The same case applies for Ruby, with immediate types(int, char...).
According to the previous 2 facts, we conclude that neither Java nor Ruby passes by reference, instead, both pass by value.
I think that fact that Ruby MRI is using C means they can't use references, and so they are using pointers, and that explains why swap fails.
I hope that the idea is clear now.