1

I had in C# an array of my custom class Entity. Due to different types of entities which I created and the way C# polymorphism worked, I chose to keep the different entity types in one entity array (i.e. I had the Player entity in the Entity array, the Enemy entity, etc.). However, in C++, using a vector of Entities, when i declare a unique Entity such as a Player, it seems to lose all the values it has as a Player, maintaining only those it has as an Entity. Is this an oversight on my part, or are the rules of polymorphism different in C++? How can I fix this?

Lorkenpeist
  • 1,475
  • 2
  • 13
  • 26
Oracular
  • 367
  • 1
  • 4
  • 13

2 Answers2

2

Object slicing in C++

Sometimes also called the slicing problem, occurs if a superclass instance is assigned its value from a subclass instance, member variables defined in the subclass cannot be copied, since the superclass has no place to store them. This only happens when you pass objects by value. As Kornel pointed out, a way around this is to use vectors of pointers to objects.

See the Wikipedia entry for a nice code example. Better yet this SO thread, explains in more details the subtle bugs that can be caused by accidental slicing

Community
  • 1
  • 1
djf
  • 6,592
  • 6
  • 44
  • 62
0

In C# everything is a "reference" to an object by default. In C++ you'd need to use a pointer in the vector ( e.g. vector< Entity* > ) or a smart pointer ( unique_ptr or shared_ptr ) of your choice, to show that you're referring to the entities by themselves, and not by value.

Otherwise, the space allocated for each of your entities is the same, hence loosing any additional information.

Kornel Kisielewicz
  • 55,802
  • 15
  • 111
  • 149
  • In attempting to do this, my GetEntities function broke. I changed its type to vector and I get the error: error C2664: 'std::vector<_Ty>::vector(const std::vector<_Ty> &)' : cannot convert parameter 1 from 'std::vector<_Ty>' to 'const std::vector<_Ty> &' – Oracular May 29 '13 at 22:59
  • If you want to get all of them, the function retrieving them should be `const std::vector< Entities* >& GetEntities() const { return m_entities }"` – Kornel Kisielewicz May 29 '13 at 23:04
  • If m_entities in your example is my vector, I get an error just like the one I showed above. – Oracular May 29 '13 at 23:06
  • have you included the `const` and `&` for the return value? – Kornel Kisielewicz May 29 '13 at 23:09
  • It is just like this: vector& Level::GetEntities() const – Oracular May 29 '13 at 23:10
  • If you return from a method that is marked `const`, the return value also needs to be marked either `const` or not be a reference. – Kornel Kisielewicz May 29 '13 at 23:11
  • The error persists regardless of the const; with the const, it simply changes to "cannot convert from const std::vector<_Ty> to std::vector<_Ty> & – Oracular May 29 '13 at 23:14
  • I'm sorry, I'm very stupid. Any error beyond your 2nd comment was due to my idiocy. Thanks for the help! – Oracular May 30 '13 at 00:29