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

If I remember correctly, in Java we can pass a subclass of a function to a superclass. The code will look as follows.

// 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 this the correct term?) Instead of the usual variable of the base class.

Assuming you have two classes: the base class Aand the A-closed class B.

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

If we have a function neverGonna()that takes a class argument A, 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 are the reasons for this?

+4
4

, sizeof(A) sizeof(B) . ( ++ ..) , , , . , ( ) , A int. , ,

AAAAAAiiii

6 A, 4 . B, AAAAAABBBBB...

AAAAAABBBBBiiii

. , , , , .

Java? java- " "; ,

Fruit apple = new Apple();

apple, Fruit. java-

public void iHaveAPenIHaveA(Fruit fruit)

.

, , Java, - , ++ ( void neverGonna(A& a)).

+3

Java . (Java "".) Apple a; Java, a , Apple - . ++, , Apple a;, a Apple. , a , Apple* a;, , Apple& a;.

. Java, Apple , Fruit (, Apple Fruit), , , , - .

++ . , Fruit, Apple - , Apple , Fruit. Apple Fruit, , Apple, . .

+5

, () .

Since the function prototype determines that the type of the input argument is a base class, this copy contains only the "base" part of the object.

In other words, the original object is β€œchopped”, and your hope for polymorphism goes to waste ...

+3
source

Because passing by value will cause the splitting of objects. Consider this example:

#include <iostream>
using namespace std;

class Base
{
public:
    virtual void foo()
    {
        cout << "Base foo()" << endl;
    }
};

class Derived : public Base
{
public:
    void foo()
    {
        cout << "Derived foo()" << endl;
    }   
};

void print(Base b)
{
    b.foo(); // object will be sliced here
}

int main()
{
    Base* b = new Derived();
    print(*b); // passing by value will cause object slicing;
    return 0;
}

Since we passed the value bin print(), there will be a partition of objects, and the data Basein bwill be cropped. The result will look like this:

Base foo()

instead:

Derived foo()
+2
source

Source: https://habr.com/ru/post/1666521/


All Articles