一 dynamic_cast
<
type-id
>
(
expression
)
type-id :必须是指针或者引用
expression:必须是指针或者一个左值
基本上是用来做 子对象间的转换
1.基本的用法
class B { ... };
class C : public B { ... };
class D : public C { ... };
void f(D* pd)
{
C* pc = dynamic_cast<C*>(pd); // ok: C is a direct base class
// pc points to C subobject of pd
B* pb = dynamic_cast<B*>(pd); // ok: B is an indirect base class
// pb points to B subobject of pd
...
}
This type of conversion is called an "upcast" because it moves a pointer up a class hierarchy, from a derived class to a class it is derived from. An upcast is an implicit conversion.
If type-id is void*, a run-time check is made to determine the actual type of expression. The result is a pointer to the complete object pointed to by expression. For example:
class A { ... };
class B { ... };
void f()
{
A* pa = new A;
B* pb = new B;
void* pv = dynamic_cast<void*>(pa);
// pv now points to an object of type A
...
pv = dynamic_cast<void*>(pb);
// pv now points to an object of type B
}
If type-id is not void*, a run-time check is made to see if the object pointed to by expression can be converted to the type pointed to by type-id.
If the type of expression is a base class of the type of type-id, a run-time check is made to see if expression actually points to a complete object of the type of type-id. If this is true, the result is a pointer to a complete object of the type of type-id. For example:
class B { ... };
class D : public B { ... };
void f()
{
B* pb = new D; // unclear but ok
B* pb2 = new B;
D* pd = dynamic_cast<D*>(pb); // ok: pb actually points to a D
...
D* pd2 = dynamic_cast<D*>(pb2); // pb2 points to a B not a D
// cast was bad so pd2 == NULL
...
}
This type of conversion is called a "downcast" because it moves a pointer down a class hierarchy, from a given class to a class derived from it.
小结:
a 实际指向对象 和 b 目标对象, b 是a 的 基类(子对象),或者是2者 同级转换才成功
否则 目标为NULL;也就是说不能向下转
2 多重非虚的继承模式
Class Hierarchy Showing Multiple Inheritance
![](ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/vclang/html/vc39011.gif)
A pointer to an object of type D
can be safely cast to B
or C
. However, if D
is cast to point to an A
object, which instance of A
would result? This would result in an ambiguous casting error. To get around this problem, you can perform two unambiguous casts. For example:
void f()
{
D* pd = new D;
A* pa = dynamic_cast<A*>(pd); // error: ambiguous
B* pb = dynamic_cast<B*>(pd); // first cast to B
A* pa2 = dynamic_cast<A*>(pb); // ok: unambiguous
}
Further ambiguities can be introduced when you use virtual base classes. Consider the class hierarchy shown in the following figure.
也就是说在2意性下会失败
3.子对象间的转换
Class Hierarchy Showing Duplicate Base Classes
![](ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/vclang/html/vc39013.gif)
//pd 指向 e 对象
void f(D* pd)
{
E* pe = dynamic_cast<E*>(pd);
B* pb = pe; // upcast, implicit conversion
A* pa = pb; // upcast, implicit conversion
}
//pd 指向 e 对象
void f(D* pd)
{
B* pb = dynamic_cast<B*>(pd); // cross cast
A* pa = pb; // upcast, implicit conversion
}
也就是 所谓 cross cast
二 typeid( type-id ) typeid( expression )
此操作符返回个 const type_info &
expression 必须指向一个多态类型(带虚函数 ),并且要解引用
#include <iostream>
#include <typeinfo.h>
class Base {
public:
virtual void vvfunc() {}
};
class Derived : public Base {};
using namespace std;
int main()
{
Derived* pd = new Derived;
Base* pb = pd;
cout << typeid( pb ).name() << endl; //prints "class Base *"
cout << typeid( *pb ).name() << endl; //prints "class Derived"
cout << typeid( pd ).name() << endl; //prints "class Derived *"
cout << typeid( *pd ).name() << endl; //prints "class Derived"
delete pd;
}
// compile with: /GR /EHsc
在模版中使用
template < typename T > T max( T arg1, T arg2 ) {
cout << typeid( T ).name() << "s compared." << endl;
return ( arg1 > arg2 ? arg1 : arg2 );
}
posted on 2006-07-04 10:23
黄大仙 阅读(1322)
评论(2) 编辑 收藏 引用 所属分类:
c++