什么是C+中的动态#U转换中的侧转换或交叉转换+; < > > C++中的“侧投< /代码> /交叉投< /代码>。 有人能举例说明吗 #include <iostream> using namespace std; class A { virtual void fn(){} }; class B:public A { }; class C:public A { }; int main() { B b; C* c; { c = dynamic_cast<C*> (&b); } if(!c) { cout<<"invalid cast "<<endl; } return 0; } #包括 使用名称空间std; 甲级 { 虚空fn(){} }; B类:公共A { }; C类:公共A类 { }; int main(){ B B; C*C; { c=动态施法(&b); } 如果(!c) { 我想这对我的问题是一个更好的答案,我不确定 #include <iostream> using namespace std; class A { public: virtual ~A(){} }; class B: virtual public A { }; class C:virtual public A { }; class D:public B,public C { }; int main() { // your code goes here D d; C*c= &d; //B*b = static_cast<B*>(c);//--cross cast using static cast gives compiler error D*dd = dynamic_cast<D*>(c); B*b = dynamic_cast<B*>(c);//--cross cast using dynamic cast succeeds return 0; } #包括 使用名称空间std; 甲级 { 公众: 虚拟~A(){} }; B类:虚拟公共A { }; C类:虚拟公共A { }; D类:公共B、公共C { }; int main(){ //你的密码在这里 D; C*C=&d; //B*B=static_cast(c);/--使用static cast进行交叉转换会导致编译器错误 D*dd=动态投影(c); B*B=动态_转换(c);/--使用动态转换的交叉转换成功 返回0; }

什么是C+中的动态#U转换中的侧转换或交叉转换+; < > > C++中的“侧投< /代码> /交叉投< /代码>。 有人能举例说明吗 #include <iostream> using namespace std; class A { virtual void fn(){} }; class B:public A { }; class C:public A { }; int main() { B b; C* c; { c = dynamic_cast<C*> (&b); } if(!c) { cout<<"invalid cast "<<endl; } return 0; } #包括 使用名称空间std; 甲级 { 虚空fn(){} }; B类:公共A { }; C类:公共A类 { }; int main(){ B B; C*C; { c=动态施法(&b); } 如果(!c) { 我想这对我的问题是一个更好的答案,我不确定 #include <iostream> using namespace std; class A { public: virtual ~A(){} }; class B: virtual public A { }; class C:virtual public A { }; class D:public B,public C { }; int main() { // your code goes here D d; C*c= &d; //B*b = static_cast<B*>(c);//--cross cast using static cast gives compiler error D*dd = dynamic_cast<D*>(c); B*b = dynamic_cast<B*>(c);//--cross cast using dynamic cast succeeds return 0; } #包括 使用名称空间std; 甲级 { 公众: 虚拟~A(){} }; B类:虚拟公共A { }; C类:虚拟公共A { }; D类:公共B、公共C { }; int main(){ //你的密码在这里 D; C*C=&d; //B*B=static_cast(c);/--使用static cast进行交叉转换会导致编译器错误 D*dd=动态投影(c); B*B=动态_转换(c);/--使用动态转换的交叉转换成功 返回0; },c++,dynamic-cast,C++,Dynamic Cast,注释中对术语进行了大量解释,因此我在回答中对其进行了捆绑。但我认为提供显示代码的行为的源代码很重要,因为asker提供的源代码只考虑交叉广播是否编译 假设这个继承树(可怕的钻石): 交叉广播 crosscast或sidecast是当dynamic_cast(pRight)返回一个与Left*行为相同的Left*时。当pRight指向最原始的对象时会发生这种情况。crosscast仅适用于dynamic_cast,而不适用于reinterpret_cast或static_cast 下行和上行 Do

注释中对术语进行了大量解释,因此我在回答中对其进行了捆绑。但我认为提供显示代码的行为的源代码很重要,因为asker提供的源代码只考虑交叉广播是否编译

假设这个继承树(可怕的钻石):

交叉广播 crosscastsidecast是当dynamic_cast(pRight)返回一个与Left*行为相同的Left*时。当pRight指向最原始的对象时会发生这种情况。crosscast仅适用于dynamic_cast,而不适用于reinterpret_cast或static_cast

下行和上行 Downcast是从右*到最派生*的强制转换,可能会失败。当它可能失败时,应该使用动态强制转换,将结果设置为
nullptr
,以表示失败。常见的模式是在调试中使用动态强制转换,但在相应的发布代码中使用更快的静态强制转换,如:

#ifdef NDEBUG
return static_cast<MostDerived*>(input);
#else
auto p = dynamic_cast<MostDerived*>(input);
assert(p != nullptr && "Unable to cast input to MostDerived*");
return p; 
#endif

你在哪里得到的术语“侧投”?我认为它相当于交叉投射,但标准不使用“侧投”或“交叉投射”。它只指“最派生类型”。例如,在BJARNE StruouSoudToul C++编程语言中使用了“交叉”,Bjarne Stroustrup的第四版使用了“交叉”这个词。(不是交叉投射)。我找不到术语侧投射。也许你可以扩展你的问题来解释你在哪里找到这个术语?@wally我想侧投射是从哪里来的如果你要回答自己的问题,那么回答术语
侧投射
从哪里来可能会有帮助。我在某个地方读过(侧投射),我不知道在哪里,但我对交叉投射的观察正确吗?我在网络的某个地方读到了它(侧投射),我不知道在哪里,但我对交叉投射的观察是对的吗?根据我的理解,侧投射和交叉投射的意思都是一样的。看起来不错。但问题是这样问的,侧投射是什么?我不知道它们是否相同。可能,但没有参考,谁知道呢?看起来你们并没有回答你们自己的问题。我认为这是一个问题的一部分答案是没有人真正使用这个词。问题的另一部分是什么是交叉投射?;这也没有得到回答。似乎你只想要一个例子,但这不是问题中所写的。侧投射在cppreference上。解释中的第5.b点是错别字吗?:
BaseClass*baseClassThroughRight=left;
这段代码没有显示可怕的钻石,但可能是一头可怕的公牛,因为
实际上都不是从
基类
继承的,所以它们都有自己的“基类”副本。添加虚拟继承(
struct Left:virtual BaseClass
struct Right:virtual BaseClass
),并提供
MostDerived::behave
启用
BaseClass*BaseClass=MostDerived;
MostDerived->behave()
编译。虽然,这只可怕的公牛很好地显示了交叉转换不需要共享虚拟基类就可以工作。很好地发现,@CharlesLWilcox,这确实是一个输入错误。你是对的,虚拟继承解决了可怕的菱形问题,我注意到编译器随后强制你提供大多数派生::显式行为。因为在这种情况下,e从来没有任何含糊不清的地方,我不明白那怎么还能被称为“可怕的钻石”。
#ifdef NDEBUG
return static_cast<MostDerived*>(input);
#else
auto p = dynamic_cast<MostDerived*>(input);
assert(p != nullptr && "Unable to cast input to MostDerived*");
return p; 
#endif
#include <iostream>

struct BaseClass { virtual const char * behave() = 0; };
struct Left : BaseClass { virtual const char * behave() { return "Left"; } };
struct Right : BaseClass { virtual const char * behave() { return "Right"; } };
struct MostDerived : Left, Right { };

int main()
{
    MostDerived * mostDerived = new MostDerived();
    // implicit upcast through the diamond results in a compile-time error, ambiguous:
    // BaseClass * baseClass = mostDerived;
    Left * left = mostDerived;
    BaseClass * baseClassThroughLeft = left; // or, equivalently:
    // BaseClass * baseClassThroughLeft = reinterpret_cast<Left*>(mostDerived);
    Right * right = mostDerived;
    BaseClass * baseClassThroughRight = right;
    
    // this is of course ambiguous and does not compile
    //std::cout << mostDerived->behave() << std::endl;
    
    // note, only the right has a pointer value of 8 more
    // the two BaseClass pointers point to the same as left,
    // as does mostDerived
    std::cout << "left:  " << left << std::endl << "right: " << right << std::endl 
              << mostDerived << std::endl << baseClassThroughRight << std::endl 
              << baseClassThroughLeft << std::endl;

    std::cout << "Cast Left BaseClass * expression to Right *" << std::endl;
    std::cout << "with static_cast, behaves as " 
              << static_cast<Right *>(baseClassThroughLeft)->behave() 
              << " at addr: " << static_cast<Right *>(baseClassThroughLeft) << std::endl;
    std::cout << "with dynamic_cast, behaves as "
              << dynamic_cast<Right *>(baseClassThroughLeft)->behave() 
              << " at addr: " << dynamic_cast<Right *>(baseClassThroughLeft) << std::endl;
              
    std::cout << "Cast Right BaseClass * expression to Left *" << std::endl;
    std::cout << "with static_cast, behaves as " 
              << static_cast<Left *>(baseClassThroughRight)->behave() 
              << " at addr: " << static_cast<Left *>(baseClassThroughRight) << std::endl;
    std::cout << "with dynamic_cast, behaves as "
              << dynamic_cast<Left *>(baseClassThroughRight)->behave() 
              << " at addr: " << dynamic_cast<Left *>(baseClassThroughRight) << std::endl;

    delete mostDerived;
    return 0;
}
left:  0xeffeb0
right: 0xeffeb8
0xeffeb0
0xeffeb8
0xeffeb0
Cast Left BaseClass * expression to Right *
with static_cast, behaves as Left at addr: 0xeffeb0
with dynamic_cast, behaves as Right at addr: 0xeffeb8
Cast Right BaseClass * expression to Left *
with static_cast, behaves as Right at addr: 0xeffeb8
with dynamic_cast, behaves as Left at addr: 0xeffeb0