在内存图中需要帮助

时间:2011-12-29 15:48:42

标签: c++ casting

我正在学习C ++。

我希望有一个很好的内存视图,比如下面的代码行运行时会有什么内容。

   // dynamic_cast
  #include <iostream>
  #include <exception>
  using namespace std;

  class CBase { virtual void dummy() {} };
  class CDerived: public CBase { int a; };

  int main () {
    try {
     CBase * pba = new CDerived;
     CBase * pbb = new CBase;
     CDerived * pd;

     pd = dynamic_cast<CDerived*>(pba);
     if (pd==0) cout << "Null pointer on first type-cast" << endl;

     pd = dynamic_cast<CDerived*>(pbb);
     if (pd==0) cout << "Null pointer on second type-cast" << endl;

     } catch (exception& e) {cout << "Exception: " << e.what();}
     system("PAUSE");
     return 0;
     }

请有人帮帮我..?

2 个答案:

答案 0 :(得分:1)

我不太确定你的实际问题是什么,但我假设它是关于dynamic_cast&lt;&gt;()的工作方式。从实际的角度来看,内部实施方式并不重要,特别是对于不同的系统实施方式不同。 Stanley Lippman的书(“C ++对象模型内部”)现在有点过时,但仍然很好地描述了这些细节以形成心理图像。需要注意的重要一点是,使用dynamic_cast&lt;&gt;()不仅可以查看具有不同类型的对象,还可能进行一些小调整,但可能需要在类似于继承树的内部表示中进行搜索。

也就是说,dynamic_cast(pba)大致如下:

  1. 获取指向内部类型信息的指针(通常称为“虚函数指针表”或“vtbl”,尽管当前实现不使用vanilla虚函数指针表),其标识类型。为此,dyanmic_cast的参数的静态类型(在本例中为“CBase”)需要至少有一个虚函数。
  2. 此对象中的类型信息可能与目标类型一致(例如,在您的示例中就是这种情况),在这种情况下,系统会对指针进行必要的调整(在某些情况下需要对多重继承进行调整)和返回相应的指针。
  3. 否则,即如果目标类型可以是对象的动态类型的基类,则系统尝试在动态类型的基类中找到目标类型。在单继承的情况下,这相当简单,但如果涉及多重继承,则可能涉及相当多的搜索。
  4. 也就是说,使用dynamic_cast&lt;&gt;()经常会产生将性能问题引入程序的可能性。但是,在必要时不使用它会产生崩溃程序的可能性。通常,使用dynamic_cast&lt;&gt;()的需求相对较少。如果您发现自己使用了dynamic_cast&lt;&gt;(),那么您的设计几乎肯定存在缺陷。

答案 1 :(得分:0)

pd = dynamic_cast<CDerived*>(pba);之后,情况如下:

pba ---> [CDerived]
          ^
pd -------'

pbb ---> [CBase]

即,pbapd指向同一个对象。然而,它们的类型不同。

pd = dynamic_cast<CDerived*>(pbb);之后,pd将为0(null),因为广告投放无效:

pba ---> [CDerived]

pd ----> (null)

pbb ---> [CBase]