polymorphism with objects/adresses

Here goes my question. i understand how upcasting and late binding works when it is used in a global function. i have always seen it used when the argument of the global function is a reference or a pointer to a base class object, but not an object itself. ie:

class Instrument {
public:
virtual void play(int) const {
cout << "Instrument::play" << endl;
}
};

class Wind : public Instrument {
public:
void play(int) const {
cout << "Wind::play" << endl;
}
};

void tune(Instrument& i) {
i.play(3);
}

void tune2(Instrument i) {
i.play(3);
}

I know it is not the usual to pass an object by value, but in this case, would upcasting and late binding occur for tune2, like it does for tune?

Many thanx
tune2 gets an object of type Instrument. When you have an object of type instrument, you get instrument behavior.

1
2
3
4
5
6
7
8
9
int main()
{
   wind flute ;
   tune2(flute) ;

   // is equivalent to:
   instrument temp = flute ;
   tune2(temp) ;
}
Last edited on
Look for `object slicing'
This is not upcasting. This is known as "object slicing". It's [usually] a bad thing.

What's happening in tune2 is you are creating a copy of the object. However you are only copying the Instrument portion of the object. The information specific to the Wind class is thrown away.

For a more clear example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Parent
{
  int p;
};

class Child : public Parent
{
  int c;
};

void sliceme(Parent obj)
{
  // obj is sliced!
}

int main()
{
  Child child;
  sliceme( child );
}


'child' inside of main has both a 'p' and a 'c' member. However the 'obj' in sliceme has only a 'p' member. The 'c' member is dropped in the copy.

This can be very dangerous because it's possible to have some information in the parent class rely on information in the child class.
Last edited on
i in tune2 is always of type Instrument so i.play(3); will always call Instrument::play. If you try to pass a Wind object to tune2 what will happen is that i will be constructed using the Instrument copy constructor.
> it's possible to have some information in the parent class rely on information in the child class.
¿could you provide an example? you shouldn't recognize your children.
One thing that comes to mind is a custom RTTI mechanism:

1
2
3
4
5
6
7
8
9
10
11
enum type
{
  parent,
  child_a,
  child_b
};

class Parent
{
  type whattypeisthis;  // set to 'parent' if the class is a parent, or 'child_a' if it's a child, etc.
};


If the object is sliced, that member would be set incorrectly.

Of course... this could just be considered a reason why you should just use the built in RTTI instead of doing something custom.
Last edited on
Many many thanx to all you. I really was thinking about what u are talking about, without knowing the proper term, but as i did not see it in the book i am learning from (at least not yet), i was very doubtful. I will read your answers more cautiously later to get the full message. again thanx!
Topic archived. No new replies allowed.