2013-06-20 12 views
5

私はクラスBでのオブジェクトの種類を確認します。チェックaはタイプAのオブジェクトの場合A.</p> <pre><code>class A { }; class B : public A { }; </code></pre> <p>そして、私は3つのオブジェクトを持っているから継承C++ 11

A* a = new A(); 
A* a2 = new B(); 
B* b = new B(); 

私がしたい、A2がタイプB(ないA)のオブジェクトであり、BはタイプB

の目的であるIは、比較を入力しようとしたが、それは私に正解を与えません。

cout << (typeid(*a) == typeid(A)) << endl; // -> 1 
cout << (typeid(*a2) == typeid(A)) << endl; // -> 1 
cout << (typeid(*b) == typeid(A)) << endl; // -> 0 

cout << (typeid(*a) == typeid(B)) << endl; // -> 0 
cout << (typeid(*a2) == typeid(B)) << endl; // -> 0 
cout << (typeid(*b) == typeid(B)) << endl; // -> 1 

コンパイルエラーが発生しました。

B* derived = dynamic_cast<B*>(a); 
if (derived) { 
    cout << "a is B"; 
} 
derived = dynamic_cast<B*>(a2); 
if (derived) { 
    cout << "a2 is B"; 
} 
derived = dynamic_cast<B*>(b); 
if (derived) { 
    cout << "b is B"; 
} 

typename.cpp: In function 'int main(int, char**)': 
typename.cpp:27:36: error: cannot dynamic_cast 'a' (of type 'class A*') to type 'class B*' (source type is not polymorphic) 
    B* derived = dynamic_cast<B*>(a); 
            ^
typename.cpp:31:34: error: cannot dynamic_cast 'a2' (of type 'class A*') to type 'class B*' (source type is not polymorphic) 
    derived = dynamic_cast<B*>(a2); 

私はスタティックキャスティングを使用しましたが、私は答えが間違っています。

B* derived = static_cast<B*>(a); 
if (derived) { 
    cout << "a is B"; // -> YES 
} 
derived = static_cast<B*>(a2); 
if (derived) { 
    cout << "a2 is B"; // -> YES 
} 
derived = dynamic_cast<B*>(b); 
if (derived) { 
    cout << "b is B"; // -> YES 
} 

C++11でオブジェクトタイプを正しく識別するにはどうすればよいですか?

+0

'* a'は' A'型で、 '* b'はその宣言ごとに' B'型です。 –

+0

動的キャストは仮想でしか機能しませんが、コードには仮想機能はありません。 –

+0

コードに似た最適な最小限のソリューション:http://coliru.stacked-crooked.com/view?id=7150bf0db7988cf1d2988aba99c72392-3b440a87a52fe2ae7c853c82f4c5144f – chris

答えて

10

一部のクラスは多型であり、一部は非多型です。

多型クラスには、1つ以上の仮想関数(継承されている可能性があります)があり、非多型クラスにはゼロ仮想関数があります。

あなたのAとBは多型ではありません。ポリモーフィッククラス店の

#include <iostream> 
#include <typeinfo> 

using namespace std; 

struct A 
{ 
    virtual ~A() {}; // add virtual function 
}; 

class B : public A 
{ 
}; 

A* a = new A(); 
A* a2 = new B(); 
B* b = new B(); 

int main() 
{ 
    cout << (typeid(*a) == typeid(A)) << endl; // -> 1 
    cout << (typeid(*a2) == typeid(A)) << endl; // -> 0 <-- CHANGED 
    cout << (typeid(*b) == typeid(A)) << endl; // -> 0 

    cout << (typeid(*a) == typeid(B)) << endl; // -> 0 
    cout << (typeid(*a2) == typeid(B)) << endl; // -> 1 <-- CHANGED 
    cout << (typeid(*b) == typeid(B)) << endl; // -> 1 
} 

は、インスタンスの実行時にその最も派生オブジェクトの動的な型:AとBの

多型バージョンは、あなたが望む行動を示すであろう。

(あなたの例でa2は、型へのポインタAであり、そしてA型のオブジェクトを指しているが、このオブジェクトは、タイプBの最もdervivedオブジェクトのみ基本クラスサブオブジェクトありますa2を照会するとき何を取得したいことは、この最も派生オブジェクトBの一種である。このためには、ポリモーフィッククラスが必要。)

最も派生オブジェクト(だけでなく、仮想のdynamic_casttypeidをサポートどのように多型のクラスであることファンクションディスパッチ)。

非多型クラスはこの情報を持たないため、コンパイル時に知られている静的型しか報告できません。非多型クラスは、よりコンパクトで効率的であり、多型クラスです。そのため、すべてのC++クラスが多型であるわけではありません。言語は、パフォーマンスと機能の間のトレードオフを選択するプログラマにそれを任せます。例えば:私のシステムで

struct X { int x; }; 
struct Y : X {}; 
struct Z : Y {}; 

Z非多型intと同じで、sizeof(Z) == 4 bytesです。

Z多型、 sizeof(Z) == 16 bytesを行った後、今
struct X { int x; virtual ~X() {}; }; 
struct Y : X {}; 
struct Z : Y {}; 

。したがって、各Zインスタンスは実行時に型情報を格納する必要があるため、Zの配列は300%大きくなりました。

+1

http://stackoverflow.com/questions/17221668/why-do-we-need-to -use-virtual-a-default-of-a-in-c – prosseek

+2

@Sharth:いいえ、[それは本当ではない](http://stackoverflow.com/a/17222286/560648);あなたは_どちらかのケースでそれを取得しません。 –

+0

@LightnessRacesinOrbit、@prosseek:訂正ありがとうございます。私はそれが '= default'の主な理由の一つだと考えていました。 –

関連する問題

 関連する問題