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.
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.