23555


C++ には、実行時の型情報を取得する `typeid()` 演算子が存在します。  
基底クラスのポインタが様々な派生クラスのアドレスを指している可能性がある場合に、この `typeid()`
演算子を用いて実行時にどのクラスのオブジェクトなのかを調べ、それぞれに適した処理を実行したいのですが、上手くいきません。

コードは以下の通りです：

[code]

    #include <iostream>
    #include <vector>
    #include <typeinfo>
    
    using namespace std;
    
    class Base {};
    class A: public Base {};
    class B: public Base {};
    class C: public Base {};
    
    int main() {
        vector<Base*> objects;
        A a;    objects.push_back(&a);
        B b;    objects.push_back(&b);
        C c;    objects.push_back(&c);
    
        for (int i = 0; i < objects.size(); i++) {
            cout << "object " << i << ": " << endl;
            cout << "name: " << typeid(*objects[i]).name() << endl;
            if (typeid(*objects[i]) == typeid(A)) {
                cout << "Class A" << endl;
            } else if (typeid(*objects[i]) == typeid(B)) {
                cout << "Class B" << endl;
            } else if (typeid(*objects[i]) == typeid(C)) {
                cout << "Class C" << endl;
            } else {
                cout << "Unexpected Class" << endl;
            }
            cout << endl;
        }
    }
    
[/code]

上記のコードでは、以下のような出力を期待しています：

> object 0:  
>  name: A  
>  Class A
>
> object 1:  
>  name: B  
>  Class B
>
> object 2:  
>  name: C  
>  Class C

しかし、実際にコンパイル・実行してみると、次のような出力になります：

> object 0:  
>  name: 4Base  
>  Unexpected Class
>
> object 1:  
>  name: 4Base  
>  Unexpected Class
>
> object 2:  
>  name: 4Base  
>  Unexpected Class

このように、すべてのオブジェクトが `Base` クラスだと判定されてしまいます。

恐らく `typeid()` 演算子の使い方が間違えているのだろうとは考えているのですが、どこがいけないのか分かりません。

宜しくお願いいたします。

* * *

使用環境：  
OS X El Capitan (10.11.4)  
Xcode Version 7.3 (7D175)


CC BY-SA 3.0
2016-03-28T12:02:16.900
23552
2016-03-28T12:47:24.060
14965
question
c++
C++ で実行時型情報 (RTTI) がうまく扱えない


web で検索しただけなので詳しくはありませんが、仮想関数が必要らしいですね。

[code]

    #include <iostream>
    #include <vector>
    #include <typeinfo>
    
    using namespace std;
    
    class Base { public: virtual void print_type(void) =0; };
    class A: public Base { void print_type(void) { cout << "A" << endl; } };
    class B: public Base { void print_type(void) { cout << "B" << endl; } };
    class C: public Base { void print_type(void) { cout << "C" << endl; } };
    
    int main() {
        vector<Base*> objects;
        A a;    objects.push_back(&a);
        B b;    objects.push_back(&b);
        C c;    objects.push_back(&c);
    
        for (int i = 0; i < objects.size(); i++) {
            cout << "object " << i << ": " << endl;
            cout << "name: " << typeid(*objects[i]).name() << endl;
            objects[i]->print_type();
            if (typeid(*objects[i]) == typeid(A)) {
                cout << "Class A" << endl;
            } else if (typeid(*objects[i]) == typeid(B)) {
                cout << "Class B" << endl;
            } else if (typeid(*objects[i]) == typeid(C)) {
                cout << "Class C" << endl;
            } else {
                cout << "Unexpected Class" << endl;
            }
            cout << endl;
        }
    }
    
[/code]

以下のように出力されました。

[code]

    object 0: 
    name: 1A
    A
    Class A
    
    object 1: 
    name: 1B
    B
    Class B
    
    object 2: 
    name: 1C
    C
    Class C
    
[/code]


CC BY-SA 3.0
2016-03-28T12:47:24.060
23555
2016-03-28T12:47:24.060
5288
23552
answer