Polymorphism is the ability of an object to take on multiple forms. In C++, polymorphism can be achieved through function overloading, function overriding, and templates. Polymorphism can occur at compile-time and run-time, and the main difference between them is when the actual function to be called is determined.
Compile-time polymorphism: Compile-time polymorphism is also known as static polymorphism or early binding. It occurs when the actual function to be called is determined at compile-time based on the types and number of arguments passed to the function. In C++, compile-time polymorphism is achieved through function overloading and templates.
Function overloading allows you to define multiple functions with the same name but with different parameter lists. When a function is called, the compiler determines which version of the function to call based on the types and number of arguments passed to the function. This determination is made at compile-time, hence the term "compile-time polymorphism". For example:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int main() {
int x = add(1, 2); // calls int add(int, int)
double y = add(3.5, 2.5); // calls double add(double, double)
return 0;
}
In this example, the compiler determines which version of the add() function to call based on the types of the arguments passed to the function. This determination is made at compile-time.
Templates in C++ allow you to define generic functions that can work with different types of arguments. The actual function to be called is determined at compile-time based on the types of the arguments passed to the function. For example:
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
int x = add(1, 2); // calls int add(int, int)
double y = add(3.5, 2.5); // calls double add(double, double)
return 0;
}
In this example, we define a template function called add() that takes two arguments of the same type and returns their sum. The actual function to be called is determined at compile-time based on the types of the arguments passed to the function.
Run-time polymorphism: Run-time polymorphism is also known as dynamic polymorphism or late binding. It occurs when the actual function to be called is determined at run-time based on the type of the object that the function is called on. In C++, run-time polymorphism is achieved through virtual functions and function overriding.
Virtual functions are functions that are declared in a base class and can be overridden in a derived class. When a virtual function is called through a pointer or reference to a base class object, the actual function that is called depends on the type of the object that the pointer or reference points to. This determination is made at run-time, hence the term "run-time polymorphism". For example:
class MyBaseClass {
public:
virtual void myVirtualFunction() {
std::cout << "Base class function called" << std::endl;
}
};
class MyDerivedClass : public MyBaseClass {
public:
void myVirtualFunction() override {
std::cout << "Derived class function called" << std::endl;
}
};
int main() {
MyBaseClass* obj1 = new MyBaseClass();
MyBaseClass* obj2 = new MyDerivedClass();
obj1->myVirtualFunction(); // calls MyBaseClass::myVirtualFunction()
obj2->myVirtualFunction(); // calls MyDerivedClass::myVirtual
}