【C/C++学習】その5、dynamic_cast
12646 ワード
dynamic_cast (expression)
クラスのポインタまたは参照を継承階層に沿って安全に変換できます.ただし、ポインタは有効でなければなりません.0(値が0のポインタにdynamic_castを適用しても、結果は0)またはオブジェクトを指す必要があります.彼はクラスオブジェクトベースのポインタと参照のタイプ変換しか受け入れません!
クラス階層で変換する場合dynamic_义齿キャストの効果は同じです!
彼は新しいタイプの値を返すか、異常を投げ出すか!
コードを見てみましょう.
出力結果は次のとおりです.
クラスのポインタまたは参照を継承階層に沿って安全に変換できます.ただし、ポインタは有効でなければなりません.0(値が0のポインタにdynamic_castを適用しても、結果は0)またはオブジェクトを指す必要があります.彼はクラスオブジェクトベースのポインタと参照のタイプ変換しか受け入れません!
クラス階層で変換する場合dynamic_义齿キャストの効果は同じです!
彼は新しいタイプの値を返すか、異常を投げ出すか!
コードを見てみましょう.
#include<iostream>
using namespace std;
struct V {
virtual void f() {}; // must be polymorphic to use runtime-checked dynamic_cast
};
struct A : virtual V {};
struct B : virtual V {
B(V* v, A* a) {
// casts during construction
dynamic_cast<B*>(v); // well-defined: v of type V*, V base of B, results in B*
dynamic_cast<B*>(a); // undefined behavior: a has type A*, A not a base of B
}
};
struct D : A, B {
D() : B((A*)this, this) { }
};
struct Base {
virtual ~Base() {}
};
struct Derived: Base {
virtual void name() {}
};
struct Some {
virtual ~Some() {}
};
int main(void)
{
D d;
A& a = d; //upcast dynamic_cast
D& new_d = dynamic_cast<D&>(a);//downcast
B& new_b = dynamic_cast<B&>(a);//sidecast
Base* b1 = new Base;
if(Derived* d = dynamic_cast<Derived*>(b1))
{
cout << "downcast from b1 to d succeful" << endl;
d->name();
}
Base* b2 = new Derived;
if(Derived* d = dynamic_cast<Derived*>(b2))
{
cout << "downcast from b2 to d successful" << endl;
d->name();
}
if(Some *d = dynamic_cast<Some*>(b1))
{
cout << "downcast from b1 to Some Successful" << endl;
//d->name();
}
delete b1;
delete b2;
return 0;
}
出力結果は次のとおりです.
downcast from b2 to d successful
, dynamic_cast !
dynamic_cast<Type&>(val);
Type ,val , val Type , val Type ,dynamic_cast val Type& 。
, !
:
1、 :static_cast dynamic_cast , , ;
2、 :static_cast dynamic_cast , static_cast ,dynamic_cast ; ,static_cast ;
3、 :dynamic_cast , static_cast ; reinterpret_cast , , ;
1) If the type of
expression is the exactly
new_type or a less cv-qualified version of
new_type, the result is
expression.
2) If the value of
expression is the null pointer value, the result is the null pointer value of type
new_type
3) If
new_type is a pointer or reference to
Base, and the type of
expression is a pointer or reference to
Derived, where
Base is a unique, accessible base class of
Derived, the result is a pointer or reference to the
Base class subobject within the
Derived object pointed or identified by
expression. (note: implicit cast and static_cast can perform this conversion as well)
4) If
expression is a pointer or reference to a polymorphic type, and
new_type is a pointer to
void, the result is a pointer to the most derived object pointed or referenced by
expression.
5) If
expression is a pointer or reference to a polymorphic type
Base, and
new_type is a pointer or reference to the type
Derived a run-time check is performed:
a) The most derived object pointed/identified by
expression is examined. If, in that object,
expressionpoints/referes to a public base of
Derived, and if only one subobject of
Derived type is derived from the subobject pointed/identified by
expression, then the result of the cast points/refers to that
Derivedsubobject. (this is known as the "downcast")
b) Otherwise, if
expression points/refers to a public base of the most derived object, and, simultanously, the most derived object has an unambiguous public base class of type
Derived, the result of the cast points/refers to that
Derived (this is known as the "sidecast")
c) Otherwise, the runtime check fails. If the dynamic_cast is used on pointers, the null pointer value of type
new_type is returned. If it was used on references, the exception
std::bad_cast is thrown.
6) When
dynamic_cast is used in a constructor or a destructor (directly or indirectly), and
expression refers to the object that's currently under construction/destruction, the object is considered to be the most derived object. If
new_type is not a pointer or reference to the construction's/destructor's own class or one of its bases, the behavior is undefined.
dynamic_cast , , 。 , dynamic_cast null。
2012/8/10
jofranks