dynamic_cast не работает при приведении базового класса к производному классу - PullRequest
0 голосов
/ 06 мая 2020

У меня есть два класса: базовый и производный. Базовый класс имеет виртуальный метод.

Вот мой тестовый пример:

class Base
{
public:
    virtual void Hello() { cout << "-> Hello Base" << endl; }
};

class Derived: public Base
{
public:
    void Hello() { cout << "-> Hello Derived" << endl; }
};

int main()
{
    Base *mBase = new Base;
    // something to do 
    ....

    Derived *mDerived = dynamic_cast<Derived*>(mBase);
    mDerived->Hello();

    return 0;
}

Я хочу использовать метод Hello() класса, полученного после приведения mBase на mDerived.

Но проблема в том, что, когда я пытаюсь использовать dynamic_cast, оно взламывает sh приложение, если нет, если я использую reinterpret_cast метод Hello() из * Будет вызван класс 1014 *.

Результат в случае dynamic_cast:

Segmentation fault (core dumped)

Результат в случае dynamic_cast:

-> Hello Base

Ответы [ 2 ]

3 голосов
/ 06 мая 2020

dynamic_cast завершается ошибкой при приведении базового класса к производному классу

Это то, что должно произойти. Когда вы динамически c приводите указатель к объекту, чей динамический c тип не является приведенным типом, в результате вы получаете нулевой указатель.

В вашем примере вы косвенно используете нулевой указатель и попытайтесь вызвать функцию-член, которая приводит к неопределенному поведению.

При использовании динамического преобразования c вы всегда должны проверять, получили ли вы значение null.

, если я использую reinterpret_cast ...

Тогда поведение все равно будет неопределенным, потому что вы будете косвенно указывать через указатель на несуществующий объект. Если вы не создадите экземпляр производного класса, вы не сможете вызвать его функцию-член non stati c.

Вы можете преобразовать базовый экземпляр в производный, например:

Base b;
Derived d = b;

Что происходит, так это то, что базовый подобъект производного экземпляра инициализируется копией из b.

0 голосов
/ 06 мая 2020

Две проблемы в вашем коде: Base должен иметь виртуальный деструктор, чтобы Dervied isntances можно было правильно уничтожить с помощью указателя на Base. Тогда вы не создаете объект типа Derived, поэтому приведение не может быть успешным. dynamic_cast может потерпеть неудачу, и вам следует проверить его результат, не является ли он nullptr. Также вы забыли удалить созданный объект.

Если вы действительно создаете экземпляр типа Derived, ваш код работает:

#include <iostream>
using std::cout;
using std::endl;

class Base
{
public:
    virtual void Hello() { cout << "-> Hello Base" << endl; }
    virtual ~Base(){}
};

class Derived: public Base
{
public:
    void Hello() { cout << "-> Hello Derived" << endl; }
};

int main()
{
    Base* mBase = new Derived;
    Derived *mDerived = dynamic_cast<Derived*>(mBase);
    if (mDerived) mDerived->Hello();
    delete mBase;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...