2009-11-07 97 views
1

看到下面的代码:将这项工作类型转换C++

ap = &abr; 

为什么这里的代码使用动态转换从here

采取

void simple_dynamic_casts() 
{ 
    AB ab; 

    B* bp = (B*)&ab; // cast needed to break protection 
    A* ap = &ab;  // public derivation, no cast needed 

    AB& abr = dynamic_cast<AB&>(*bp); // succeeds 

    ap = dynamic_cast<A*>(bp);   assert(ap != NULL); 
    bp = dynamic_cast<B*>(ap);   assert(bp == NULL); 
    ap = dynamic_cast<A*>(&abr);  assert(ap != NULL); 
    bp = dynamic_cast<B*>(&abr);  assert(bp == NULL); 
} 

代码。我还没有试过编译这段代码。

+0

为什么-1表示 – 2009-11-07 18:44:19

回答

3

他们使用dynamic_cast显示它做什么。所以,这就是你的“为什么”问题的答案。

否则,该网页给出的解释是不正确。您尝试使用的资源要么严重过时,要么与某些特定的质量较差的编译器绑定。在页面顶部的“新兴的C++标准......”等字是一个死胡同。 C++标准在11年前成为现实。 (意思是说网站是不是C++一般和特别dynamic_cast一个很好的资源,如果这是你在找什么。)

这里是他们的类定义

class A   { public: virtual void f(); }; 
class B   { public: virtual void g(); }; 
class AB :  public virtual A, private B { }; 

演员

AB& abr = dynamic_cast<AB&>(*bp); // they say: succeeds 

不是成功。它将抛出bad_cast例外,因为B不是AB的公共基类。 dynamic_cast不能用于打倒downcasts中的保护。

铸造

bp = dynamic_cast<B*>(&abr); 

甚至不会编译,因为非法upcasts(断裂保护)甚至被dynamic_cast在编译时拒绝(即,代码是形成不良的)。请注意,在这种情况下,dynamic_cast没有什么特别之处。对于upcasts,dynamic_cast相当于static_cast或完全不播放。由于B是一个私人的基地,上述演员将不会编译。作者似乎错误地认为在这种情况下dynamic_cast应该返回空指针。

至于ap = &abr - 是的,它会奏效。它没什么错,只要AAB的公共基地。

+0

well bp = dynamic_cast (ap)确实会编译。然而断言失败。 – 2009-11-07 19:12:40

+0

糟糕...不应该包含该演员。这是一个十字架,而不是一个倒戈。我修好了它。谢谢。 – AnT 2009-11-07 19:18:59

1

是的。一个指向类的指针总是可以隐式转换为指向公共基类的指针;在这种情况下,您将从AB*转换为A*。允许使用dynamic_cast,但不是必需的。

这与第二次转换没有什么不同(A* ap = &ab;)。

该代码使用dynamic_cast来说明如何工作。

0

为什么代码在这里使用动态投射。

dynamic_cast运算符允许您在运行时检查转换是否有效。如果不是,它将返回null(因此调用assert())。

将这项工作

试试看... :)