C ++ - 在派生类上使用的typeid()不返回正确的类型

时间:2012-07-14 13:07:19

标签: c++ inheritance typeid

也许我误解了继承如何在这里工作,但这是我的问题:

我有一个类Option,以及一个派生自它的类RoomOption。我有另一个课室,里面有一个shared_ptrs的矢量。在主要内容中,我向该向量添加了一个RoomOption。然后,使用typeid()我检查类型,它告诉我它的选项。根据我的阅读,typeid应该返回派生类型,而shared_ptrs不会导致切片,所以我不确定我做错了什么。

以下是代码:

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];
}

主:

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>

在我看来,可能在添加或获取选项时,由于返回/参数类型,RoomOption会被转换为选项。如果是这种情况那么我应该如何存储多种类型的矢量?或者我错了吗? = \

3 个答案:

答案 0 :(得分:15)

对于多态(对于具有至少一个虚函数的类)和非多态类型,typeid的工作方式不同:

  • 如果类型是多态的,则表示它的相应typeinfo结构在运行时确定(vtable指针通常用于此目的,但这是一个实现细节)

  • 如果类型不是多态的,则在编译时确定相应的typeinfo结构

在你的情况下,你实际上有一个多态类Option,但shared_ptr<Option> itsef根本不是多态的。它基本上是一个容纳Option*的容器。 Optionshared_ptr<Option>之间绝对存在 no 继承关系。

如果要获取真实类型,首先需要使用Option* shared_ptr<Option>::get()从容器中提取实际指针:

Option * myPtr = player->getRoom()->getOption(0).get();
cout << typeid(*myPtr).name(); << endl;

或者(完全相同):

Option& myPtr = *player->getRoom()->getOption(0);
cout << typeid(myPtr).name(); << endl;

答案 1 :(得分:1)

shared_ptr<Option>指向的对象类型是其值的一部分,而不是其类型。所以这行代码被打破了:

cout<<typeid(player->getRoom()->getOption(0)).name()<<endl; 

你想要这个:

cout<<typeid(player->getRoom()->getOption(0).get()).name()<<endl; 

或者也许:

cout<<typeid(*(player->getRoom()->getOption(0))).name()<<endl; 

typeid的作用是告诉你传递给它的事物的实际类型。你传递了shared_ptr<Option>。它不会查看对象内部以查看它包含的内容。

答案 2 :(得分:1)

首先获取shared_ptr的typeid。

然后你应该使用dynamic_cast而不是typeid。 E.g:

if (dynamic_cast<RoomOption*>(player->getRoom()->getOption(0).get()) != 0){
    cout << "Its a RoomOption!" << endl;
}