Search code examples
c++objectinheritancecompiler-optimizationpass-by-value

Pass by value an object in context of inheritance in C++


I am learning C++ and in my teacher's course, he explained that polymorphism is not compatible with passing by value.

He explained that when you pass an object by value to a method, the compiler generates a copy of the object in the stack, and for optimization reasons he chooses to create a copy of the type of the parent class.

For instance, say I have a class called A, and the class B is a child class of A. If I pass by value an object of type B, the compiler create a copy of it on the stack but of type A.

My questions are :

  • Is it always the case?

  • Say I created a Copy Constructer for the class B, does the compiler then use it when I pass an object of type B by value to a method? Or does it still copies a B as an A (object slicing)? If not, why?

Thanks!

Edit : example

// in headers file
// for A
class A
{ 
    public :
        virtual void Display() const
         { cout << "A::Display() was called << endl; }
};

// for B
class B : public A
{ 
    public :
        void Display() const
         { cout << "B::Display() was called << endl; }
};

Now 3 possibles cases in another file called main.cpp:

case 1:

void f( const A & anA)
{
    anA.Display();
}

int main() 
{
    B anB;
    f (anB);
    return 0;
}

case 2:

void f( const A * anA)
{
    anA->Display();
}

int main() 
{
    A * anB = new B; 
    f ( anB );
    return 0;
}

case 3:

void f( A anA)
{
    anA.Display();
}

int main() 
{
    B anB; 
    f ( anB );
    return 0;
}

From what I've understood, case 1 and case 2 will display the wanted output (meaning "B::Display() was called"), while case 3 won't (it will output : "A::Display() was called") even though the Display method was specified as virtual in the A class.


Solution

  • Case (1) Pass by reference no slicing.

    Case (2) Pass by value (of the pointer) no slicing.

    Case (3) Pass by value: anA is copy constructed from anB only taking the top A slice. anA has no B part.

    The same slicing as case (3) occurs here:

    B b;
    A a = b;
    

    We create a B and copy construct an A from it.