8

ここで継承がどのように機能するかを誤解しているかもしれませんが、ここに私の問題があります。

クラスOptionと、それから派生したクラスRoomOptionがあります。shared_ptrsのベクトルを保持する別のクラスRoomがあります。主に、そのベクトルに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がオプションとしてキャストされることがあります。その場合、複数のタイプのベクトルをどのように格納する必要がありますか?それとも私はこれをすべて間違っていますか?= \

4

3 に答える 3

18

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;
于 2012-07-14T13:21:32.690 に答える
3

まず、shared_ptrのtypeidを取得します。

次に、typeidの代わりにdynamic_castを使用する必要があります。例えば:

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>、そのタイプではなく、その値の一部です。したがって、このコード行は壊れています。

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 に答える