As explained by previous answers, making print function in base class virtual
and implementing the print function with same signature in the derived class allows you to achieve dynamic polymorphism. In other words based on the type of object animal pointer points, determines which print function is called. C++11 introduced a keyword called override
which indicates that the function is overriding a virtual function of the base class. Following snippet shows implementation with override keyword.
#include <iostream>
using namespace std;
class Animal {
public:
string color = "Black";
virtual void print() {
cout<<"This is animal class"<<endl;
}
};
class Dog: public Animal {
public:
string color = "Grey";
void print() override {
cout<<"This is Dog class"<<endl;
}
};
int main() {
Animal *d= new Dog;
d->print();
return 0;
}
Let's understand how the dynamic polymorphism works. When you declare a function as virtual function in the base class a virtual function table gets created which contains virtual function pointers. Class contains a VPTR a pointer to virtual function table (This increase the size of the Animal object by size of the pointer which is dependent on the pointer size) In your example, when you declare a Animal class print function as virtual. VPTR (pointer to virtual function table) becomes a member of Animal class. The corresponding virtual function table looks as follows

When you create child class by deriving Animal class, Since the base class contains a virtual function, A new virtual function table gets automatically created with VPTR as a member of the derived class. This virtual function table contains a pointer to a print function. If you don't override the print function in derived class function, pointer in the virtual function table points to base class print function, this illustrated with the following diagram.

When you call print function from base class pointer, function is searched in virtual function table of the class to which base class pointer points. In your case if the Animal class pointer points to Animal object print function is searched in Animal class virtual table, If it points to Dog class then searched in the Dog class virtual function table. This is how dynamic polymorphism is achieved. As you can see function needs searched in the virtual function table. This introduces run time overhead, however in static polymorphism this is not the case where function to be called is decided at the compile time.