Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should you pass a reference instead of a value when passing a derived class object to a function with a base class parameter in C++?

Tags:

c++

If I remember correctly, in Java, we can pass a subclass to a function with a superclass. The code would look like this.

// Assume the classes were already defined, and Apple
// and Pineapple are derived from Fruit.
Fruit apple = new Apple();
Fruit pineapple = new Pineapple();

public void iHaveAPenIHaveAn(Fruit fruit) { ... } // :)
...
public static void main(String[] arg)
{
    iHaveAPenIHaveAn(apple); // Uh! Apple-pen.
    iHaveAPenIHaveAn(pineapple); // Uh! Pineapple-pen.
}

However, in C++, I noticed from here that you need to use a reference variable of the base class (Is that the proper term?) instead of a regular variable of the base class.

Assuming you have two classes: a base class A, and an A-derived class B.

class A { ... };
class B : A { ... };

If we have a neverGonna() function that takes in a class A argument, then why should the function look like this:

void neverGonna(A& a) { ... }
...
B giveYouUp;
neverGonna(giveYouUp);

instead of this?

void neverGonna(A a) { ... }
...
B letYouDown;
neverGonna(letYouDown);

What is the reasoning behind it?

like image 407
Sean Francis N. Ballais Avatar asked Dec 08 '22 19:12

Sean Francis N. Ballais


1 Answers

Objects in Java are referenced by pointers. (Java calls them "references".) If you write Apple a; in Java, the variable a is actually a pointer, pointing to an Apple object somewhere in memory. In C++ though, if you write Apple a; then the variable a contains the entire Apple object. To get pointers, you need to explicitly declare a to be a pointer variable, as in Apple* a;, or a reference, as in Apple& a;.

The same goes for function arguments. In Java, if you send an Apple to a method that expects a Fruit (assuming that Apple is a subclass of Fruit), what is actually sent is a pointer, and the object itself is stored somewhere else.

In C++, the object itself is copied, and sent to the function. However, if the function expects a Fruit object, and you send an Apple object with some extra member variables in it, the Apple won't fit in the space that the function has to receive the Fruit. The Apple object has to be converted to a Fruit object, and any apple-specific extra stuff is removed. This is called object slicing.

like image 198
Thomas Padron-McCarthy Avatar answered May 20 '23 00:05

Thomas Padron-McCarthy