运行时多态性和 dynamic_cast 需要澄清

runtime polymorphism and dynamic_cast need clarification

可能在其他地方回答了一些问题,但找不到合适的短语来提问

所以听到了。

我有基础 class A,有 child BC; (完全用于培训目的)

#include <iostream>

class A 
{ 
    public: 
        virtual void print () { std::cout<< "A::print()" << std::endl; } 
}; 

class B: public A 
{ 
    public: 
        void print () { std::cout<< "B::print()" << std::endl; } 
}; 

class C : public B 
{ 
    public: 
        void print () { std::cout<< "C::print()" << std::endl; } 
};

所以,在我的 main 中,我声明了基指针 A* bptr;后来 child 的 BC 也宣布了。

稍后 bPtr 指向 B 并调用 print 函数按预期工作; 后来 bPtr 指向 C 并调用 print 函数按预期工作;

听到的是代码,没问题听到。

int main()  
{
    A* bPtr;

    B b;
    C c;

    bPtr = &b;
    bPtr->print(); // prints B::print() - as expected;

    bPtr = &c;
    bPtr->print(); // prints C::print() - as expected;

}

听说是我的困境,我可能理解错了; 现在我这些天一直在想, dynamic_cast 也确实在上面; 但情况有所不同,或者我做错了什么。

int main()
{

    A* bPtr = new C;

    bPtr = dynamic_cast<B*>( bPtr );

    bPtr->print(); // prints C::print() - expected B::print()

    /*
        I know above can be correct with explicit call
    */

    (dynamic_cast<B*>( bPtr ))->B::print(); // B::print


    bPtr = dynamic_cast<C*>( bPtr );

    bPtr->print(); // prints C::print()

    return 0; 


    if ( B* b = dynamic_cast<B*>( bPtr ))
    {
        b->print(); // still calls C::print() anyway;
    }

}  

所以听到的是我的问题是 dynamic_cast good for and only places like if statement to determine base 和 child 之间是否存在继承或 base 和 child 之间是否存在安全转换?

if ( B* b = dynamic_cast<B*>( bPtr ))
{
        b->print(); // still calls C::print() anyway;
}

此行为与dynamic_cast无关。

虚拟调用的行为将始终取决于值的实际运行时类型。在您的第二个示例中,实际构造的唯一东西是 C,因此所有调用都将解析为 C,无论您将其称为 A:A * a = bPtr 还是 B:B * b = bPtr,它都会解析为 C::print() 因为语句 new C 将实际值构造为 C.

Dynamic_cast 只是将给定的值转换为特定类型,如果它是该类型的(子类型),否则 return nullptr。因此,将 B * 动态转换为 C * 将失败并且 return nullptr,但在您的情况下,您正在将 C * 转换为其基本类型之一,这将永远成功,永远不会改变价值本身。