Maybe I'm misunderstanding how inheritance works here, but here's my problem:
I have a class Option, and a class RoomOption that derives from it. I have another class Room which holds a vector of shared_ptrs. In main I add a RoomOption to that vector. Then, using typeid() I check the type, and it tells me its an Option. From what I've read, typeid is supposed to return derived types, and shared_ptrs dont cause slicing, so I'm not sure what I'm doing wrong.
Here's the code:
Room.h:
vector<shared_ptr<Option> > options;
void addOption(shared_ptr<Option>);
shared_ptr<Option> getOption(int);
Room.cpp:
void Room::addOption(shared_ptr<Option> option){
options.push_back(option);
}
shared_ptr<Option> Room::getOption(int i){
return options[i];
}
main:
shared_ptr<Room> outside(new Room(0, "", ""));
outside->addOption(shared_ptr<RoomOption>(new RoomOption(0, "Go inside", hallway)));
cout<<typeid(player->getRoom()->getOption(0)).name().get()<<endl;
//This line prints "class std::tr1::shared_ptr<class Option>
It occurs to me that maybe when adding or getting an Option, the RoomOption is casted as an Option due to the return/argument type. If that's the case then how am I supposed to store a vector of more than one type? Or am I getting this all wrong? =\
The typeid
works differently for polymorphic (for classes having at least one virtual function) and non-polymorphic types :
If the type is polymorphic, the corresponding typeinfo
structure which represents it is determined at run-time (the vtable pointer is commonly used for that purpose, but this is an implementation detail)
If the type isn't polymorphic, the corresponding typeinfo structure is determined at compile time
In your case, you actually have a polymorphic class Option
, but shared_ptr<Option>
itsef isn't polymorphic at all. It basically is a container holding an Option*
. There is absolutely no inheritance relation between Option
and shared_ptr<Option>
.
If you want to get the real type, you first need to extract the real pointer from its container using Option* shared_ptr<Option>::get()
:
Option * myPtr = player->getRoom()->getOption(0).get();
cout << typeid(*myPtr).name(); << endl;
Or alternatively (it is exactly the same thing) :
Option& myPtr = *player->getRoom()->getOption(0);
cout << typeid(myPtr).name(); << endl;