随笔 - 25  文章 - 29  trackbacks - 0
<2006年7月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

常用链接

留言簿(4)

随笔分类(22)

随笔档案(25)

文章分类(2)

文章档案(2)

相册

最新随笔

搜索

  •  

积分与排名

  • 积分 - 55692
  • 排名 - 402

最新评论

阅读排行榜

评论排行榜


一                 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

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


    //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 黄大仙 阅读(1332) 评论(2)  编辑 收藏 引用 所属分类: c++

FeedBack:
# re: Run time type Information 2006-07-04 14:53 沐枫
好。
还不知道dynamic_cast<void*>()能转换成真实类型的指针。有这个功能,真太好了。
等C++0x出来后,就可以用:
auto pv = dynamic_cast<void*>(...)来获取真实类型了。  回复  更多评论
  
# re: Run time type Information 2006-07-08 00:27 flyingxu
虽然是很好的文章,但是文章前面一部分和msnd上的太像了。。。可以多加些自己的理解  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理