I am learning C++ inheritance, so I tried this code by creating a Base class dynamically and made a downcast to its Derived class (obviously its not valid to downcast) in order
The reason your code behaves this way is probably because the compiler doesn't check the actual type of your object (it isn't required to unless your function is virtual
); it just calls child::who
because you told it to. That said, your code is certainly suspect.
You are statically downcasting the base class pointer to a derived class pointer, which not type-safe. C++ will not prevent you from doing this; it is up to you to ensure that your pointer really does point to an object of the derived type. Dereferencing the pointer if it does not refer to an object of the derived type is potentially undefined behaviour. You are lucky your code even prints anything at all.
You need to make sure your base class function who
is virtual
, otherwise the function call will not behave polymorphically. Keep in mind, once you add virtual
to your code, you will certainly be invoking undefined behaviour, because you are illegally downcasting to an invalid type. You can safely downcast using dynamic_cast, which will return a nullptr
if the object is not of the specified type.
You should also generally have a virtual
destructor in your base class, so that your object can be delete
d polymorphically. Speaking of which, you also need to make sure to delete
your dynamically allocated object at some point. By manually calling new
and delete
, it is very easy to leak memory like this, even if you know that you need to call delete
. std::unique_ptr and std::shared_ptr were added to the standard library in C++11 to address these concerns. Use these instead of new
and delete
in all but the most low-level code.
To summarize, here is how I suggest your code should look:
#include
#include
class parent {
public:
virtual ~parent() {}
virtual void who() {
std::cout << "I am parent";
}
};
class child : public parent {
public:
void who() override {
std::cout << "I am child";
}
};
int main() {
auto p = std::make_unique();
auto c = dynamic_cast(p.get());
if (c) // will obviously test false in this case
{
c->who();
}
}