【问题标题】:dynamic_cast and polymorphismdynamic_cast 和多态性
【发布时间】:2015-06-27 20:53:03
【问题描述】:

这是我在这个网站上的第一个问题,所以请随时强调我的用词、问题结构等方面的任何问题。

最近,我在处理多态性时开始使用dynamic_cast,并且我读到dynamic_cast 不会创建该类的另一个实例,而是创建指向该对象的指针的另一个实例。

在测试dynamic_cast 时,我遇到了这个问题。代码如下:

//main.cpp

#include <iostream>

class Base{
public:
    int BaseNum;
    virtual void BaseFunction(){};
};

class Derived : public Base{
public:
    int DerivedNum; 
    virtual void DerivedFunction(){};
};

int main(){

    Base * ptrBase = new Base;
    ptrBase->BaseNum = 0;
    Derived * ptrDerived = dynamic_cast<Derived *>(ptrBase);
    ptrDerived->DerivedNum = 1;

    std::cout << ptrBase->BaseNum << ptrDerived->DerivedNum << std::endl;

    system("pause");
    return 0;
}

程序在该行崩溃了:

ptrDerived->DerivedNum = 1;

在调试时,它说“无法读取内存”。我的结论是,如果原始内存分配是为层次结构中较高的类保留的,我不能沮丧,但我认为我可能错了。

代码哪里出错了?

【问题讨论】:

    标签: c++ inheritance polymorphism dynamic-cast


    【解决方案1】:

    在您的示例代码中,您创建了一个 Base 的新实例:

    Base * ptrBase = new Base;
    ptrBase->BaseNum = 0;
    Derived * ptrDerived = dynamic_cast<Derived *>(ptrBase);
    

    由于DerivedBase 的超集,但base 只是Derived 的子集,因此您不能将ptrBase 指向的对象称为Derived,因为它比@“小” 987654328@.

    另一方面,如果你写

    Base * ptrBase = new Derived;
    ptrBase->BaseNum = 0;
    Derived * ptrDerived = dynamic_cast<Derived *>(ptrBase);
    

    那么一切都很好,因为现在ptrBase指向的对象是Derived

    使用dynamic_cast,由程序员确保转换成功。

    【讨论】:

    • 编译器确保转换是合法的。程序员必须确保转换成功,因为编译器无法在编译时验证。
    【解决方案2】:

    dynamic_cast 在指定对象中定位请求的类类型,并返回指向该对象部分的指针/引用。如果找不到,则为指针转换返回 NULL,并为引用转换引发 std::bad_cast 异常。在您的示例中,它失败了,因为ptrBase 没有指向作为Derived 类实例的对象,因此对象内没有Derived 部分可以返回指向的指针,因此它返回NULL。你需要改变这个:

    Base * ptrBase = new Base;
    

    改为:

    Base * ptrBase = new Derived;
    

    【讨论】:

    • 感谢您的澄清,所以基本上 dynamic_cast 没有添加任何关于内存分配的内容。
    • 没有分配,只是一个指向现有对象中不同内存地址的指针。
    • @DiegoLiu: dynamic_cast 说“嘿,看看这是不是Derived,如果是,给我一个指向它那一边的指针。
    【解决方案3】:

    您的问题是您正在向后使用动态强制转换。

    如果你这样做了

       Base *ptrBase = new Derived ;
    

    然后就可以了。

    派生是一个基础。 基数不是派生的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-09
      • 1970-01-01
      • 2017-11-10
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多