8

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

我有一个类 Option 和一个派生自它的类 RoomOption。我有另一个类 Room,其中包含一个 shared_ptrs 向量。在 main 中,我向该向量添加了 RoomOption。然后,使用 typeid() 检查类型,它告诉我它是一个选项。根据我的阅读, typeid 应该返回派生类型,并且 shared_ptrs 不会导致切片,所以我不确定我做错了什么。

这是代码:

房间.h:

vector<shared_ptr<Option> > options;
void addOption(shared_ptr<Option>);
shared_ptr<Option> getOption(int);

房间.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 被强制转换为选项。如果是这种情况,那么我应该如何存储一种以上类型的向量?还是我把这一切都弄错了?=\

4

3 回答 3

18

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

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

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

在您的情况下,您实际上有一个多态 class Option,但shared_ptr<Option>itef 根本不是多态的。它基本上是一个装有Option*. 和之间绝对没有继承关系。Optionshared_ptr<Option>

如果要获取真实类型,首先需要使用以下方法从其容器中提取真实指针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;
于 2012-07-14T13:21:32.690 回答
3

首先你得到了 shared_ptr 的 typeid。

然后你应该使用dynamic_cast而不是 typeid。例如:

if (dynamic_cast<RoomOption*>(player->getRoom()->getOption(0).get()) != 0){
    cout << "Its a RoomOption!" << endl;
}
于 2012-07-14T13:16:49.000 回答
1

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

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>. 它不会查看对象内部以查看其中包含的内容。

于 2012-07-14T13:11:56.727 回答