1

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.

CSstudZ
  • 101
  • 10
  • 2
    Does this answer your question? [What is object slicing?](https://stackoverflow.com/questions/274626/what-is-object-slicing) – Richard Critten Dec 12 '19 at 19:54
  • @RichardCritten Thanks. It definitely makes object slicing more understandable. However, I am still confused about the compilers optimization when it comes to passing an object (in the context of inheritance) by value **to a method** . – CSstudZ Dec 12 '19 at 19:59
  • 1
    Please add a [mcve] for your question so I am sure I understand what you are asking. – Richard Critten Dec 12 '19 at 20:01
  • object slicing is the answer to what happens when you pass some polymorphic object to a function. You dont need optimizations for this to go wrong – 463035818_is_not_an_ai Dec 12 '19 at 20:03
  • It’s not an optimization, exactly, that slicing occurs: it’s just that objects declared as such (not as pointers or references) in C++ always have **exactly** the type specified. – Davis Herring Dec 12 '19 at 20:11
  • I have added an edit with an example of what I mean. Thanks for your responses. What I understand from your responses and by rereading the course, is that object slicing also happens when passing a parameters to a method and that it breaks the dynamic link, and therefore the virtual specification of a method doesn't work anymore. Is that correct? – CSstudZ Dec 12 '19 at 20:18
  • 'Case 3' in the examples you added demonstrates slicing. Your original description of the question/problem doesn't seem entirely correct though. Among other things, it's not necessarily an optimization issue (as noted in other comments), and the statement 'polymorphism is not compatible with passing by value' seems overly broad without additional context. (Also, you said 'he' chooses, but I'm not sure who you're referring to there.) – scg Dec 12 '19 at 20:18
  • @scg I meant the compiler when I said "he". I should have used "it".Sorry, english is not my first language. – CSstudZ Dec 12 '19 at 20:20
  • @CSstudZ: Got it :) Don't worry, your English is good. I was just confused because the natural antecedent for 'he' would be 'your teacher', which made that part a little unclear. – scg Dec 12 '19 at 20:25

1 Answers1

1

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.

Richard Critten
  • 2,138
  • 3
  • 13
  • 16
  • Alright, I understand now. Thank you. Another question : you've said that "anA is copy constructed from anB", therefore if I create a copy constructor could I prevent this type of behavior from happening? – CSstudZ Dec 12 '19 at 20:32
  • @CSstudZ SO discourages more than 1 question per question (it would turn the site into a forum not a Q&A site). If you post another question I would be happy to try and answer it there. – Richard Critten Dec 12 '19 at 20:34
  • @CSstudZ Since this answer helped you to understand the topic, please consider accepting it. – Ted Lyngmo Dec 29 '20 at 23:06