ошибка при использовании dynamic_cast и конструктора - PullRequest
0 голосов
/ 31 октября 2018
#include "stdafx.h"
#include <iostream>
using namespace std;
class myclass {
public:
    int a;
    myclass() : a(-1){};
 };
class derivedclass : public myclass {
     public: 
     int b;
    derivedclass() : b(-2) {};
  };

int main()
{
myclass* p= new myclass;
//  derivedclass* pd = dynamic_cast<derivedclass*>(p);
derivedclass* pd = static_cast<derivedclass*>(p);
cout << pd->b << endl;

return 0;
}

У меня два вопроса.

  1. dynamic_cast не работает. Так что нужно добавить виртуальную функцию в myclass?
  2. почему pd->b не является -2, как инициализировано в конструктор?

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

dynamic_cast не работает по двум причинам.

Во-первых, как вы уже догадались, вам нужны виртуальные функции, чтобы dynamic_cast работал , то есть базовый тип myclass должен быть полиморфным.

Другая причина также касается вашего второго вопроса. В вашем коде derivedclass наследуется от myclass. Это означает, что любой объект типа derivedclass также является объектом типа myclass. не подразумевает, что любой объект типа myclass обязательно также имеет тип derivedclass, который, как вы, похоже, предполагаете.

// creates a new instance of myclass, NOT an instance of derivedclass
myclass* p= new myclass;

// assuming myclass is polymorphic, returns a type-safe pointer to a derivedclass object
// if p is not such an object, returns nullptr, which is useful for error checking
derivedclass* pd1 = dynamic_cast<derivedclass*>(p);

// this is very unsafe! pd2 is now a 'wild' pointer to an object that doesn't exist
derivedclass* pd2 = static_cast<derivedclass*>(p);

// this is Undefined Behavior: there is no such `b` in memory at pd2, and that memory
// is not yours to read from
cout << pd2->b << endl;

Причина, по которой pd->b не является -2, заключается в том, что конструктор derivedclass никогда не выполнял . Вы никогда не создавали объект derivedclass.

0 голосов
/ 31 октября 2018

dynamic_cast не работает. Так нужно добавить виртуальную функцию в производный класс?

Да. Вам нужно иметь виртуальную функцию, чтобы использовать динамическое приведение.

Кроме того, вы должны проверить, приводит ли динамическое приведение к нулевому указателю. В этом случае это приведет к нулю (если существует виртуальная функция), поскольку p не указывает на экземпляр derivedclass.

почему pd-> b не равно -2, как инициализировано в конструкторе?

Поведение не определено. Нет derivedclass или его членов никогда не было построено.

...