0

Let parent class A and a child class B be

// A.h
#include <iostream>
struct A {
    virtual void print() {
        std::cout << "A" << std::endl;
    }
};

and

#include <iostream>
#include "A.h"

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

Then in a program the following is possible:

int main() {

    A a1;
    a1.print();  // <-- "A"

    B b1;
    b1.print();  // <-- "B"
    
    A* a2 = new B();
    a2->print(); // <-- "B"
}

However, the following crashes:

B* b2 = dynamic_cast<B*>(new A());
b2->print(); // <-- Crashes

What is wrong here?

TMOTTM
  • 3,286
  • 6
  • 32
  • 63

1 Answers1

2

A does not derive from B (the reverse is true). You are creating an instance of A, not of B. Using dynamic_cast to cast an A object into a B* pointer will result in a null pointer, which you are not checking for before calling B::print(). Calling a non-static class method via a null pointer is undefined behavior, see: What will happen when I call a member function on a NULL object pointer?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I found I can use `static_cast` : `B* b2 = static_cast(new A()); b2->print(); // 'A'`. – TMOTTM Jan 03 '21 at 13:59
  • 1
    @TMOTTM still *undefined behavior*, since you are not creating a `B` instance to begin with. Give `B` some data members that `print()` accesses, and you will see that code fail at runtime. Just because it compiles doesn't make it right. – Remy Lebeau Jan 03 '21 at 17:31