Полиморфизм - это возможность объектов с одинаковым интерфейсом демонстрировать разное поведение в зависимости от их типа.
Полиморфизм - это один из ключевых принципов объектно-ориентированного программирования, позволяющий использовать один и тот же интерфейс для работы с разными типами данных. В C++ полиморфизм реализуется несколькими способами.
Типы полиморфизма в C++:
Ad-hoc полиморфизм (перегрузка функций)
Параметрический полиморфизм (шаблоны)
Полиморфизм подтипов (наследование и переопределение методов)
Ad-hoc полиморфизм (перегрузка функций)
Перегрузка функций позволяет создавать несколько функций с одним именем, но разными параметрами.
#include <iostream>
using namespace std;
// Перегрузка функции add
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
string add(string a, string b) {
return a + b;
}
int main() {
cout << add(5, 3) << endl; // Вызов int версии
cout << add(2.5, 3.7) << endl; // Вызов double версии
cout << add("Hello ", "World") << endl; // Вызов string версии
return 0;
}
Пояснение: Компилятор выбирает нужную версию функции add на основе типов переданных аргументов. Это называется статическим (compile-time) полиморфизмом.
Параметрический полиморфизм (шаблоны)
Шаблоны позволяют создавать обобщённые функции и классы, работающие с разными типами данных.
#include <iostream>
using namespace std;
// Шаблонная функция
template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
// Шаблонный класс
template <class T>
class Box {
private:
T content;
public:
void setContent(T newContent) {
content = newContent;
}
T getContent() {
return content;
}
};
int main() {
cout << max<int>(3, 5) << endl; // 5
cout << max<double>(3.2, 5.4) << endl; // 5.4
cout << max<char>('a', 'z') << endl; // z
Box<int> intBox;
intBox.setContent(123);
cout << intBox.getContent() << endl;
Box<string> stringBox;
stringBox.setContent("Hello Template!");
cout << stringBox.getContent() << endl;
return 0;
}
Пояснение: Шаблоны позволяют писать код, который работает с любым типом данных. Компилятор генерирует конкретные версии функций или классов для каждого используемого типа.
Полиморфизм подтипов
Функции определённые в базовом классе могут быть переопределены в классах наследниках, рассмотрим пример:
#include <iostream>
using namespace std;
class Animal {
public:
void makeSound() {
cout << "Some generic animal sound" << endl;
}
};
class Dog : public Animal {
public:
void makeSound() {
cout << "Woof! Woof!" << endl;
}
};
class Cat : public Animal {
public:
void makeSound() {
cout << "Meow! Meow!" << endl;
}
};
int main() {
Animal animal;
Dog dog;
Cat cat;
animal.makeSound(); // Some generic animal sound
dog.makeSound(); // Woof! Woof!
cat.makeSound(); // Meow! Meow!
// Но при работе через указатель на базовый класс:
Animal* ptr = &dog;
ptr->makeSound(); // Some generic animal sound
return 0;
}
Пояснение
В данном примере, классы Cat и Dog
переопределяют метод makeSound() базового класса.
Альтернативный подход с использованием шаблонов:
#include <iostream>
using namespace std;
class Dog {
public:
void makeSound() {
cout << "Woof! Woof!" << endl;
}
};
class Cat {
public:
void makeSound() {
cout << "Meow! Meow!" << endl;
}
};
// Шаблонная функция, демонстрирующая полиморфное поведение
template <typename T>
void playWithAnimal(T& animal) {
animal.makeSound();
}
int main() {
Dog dog;
Cat cat;
playWithAnimal(dog); // Woof! Woof!
playWithAnimal(cat); // Meow! Meow!
return 0;
}
Пояснение: Шаблоны позволяют достичь полиморфного поведения без использования наследования. Это называется "статическим полиморфизмом" или "полиморфизмом времени компиляции".
Полиморфизм в C++ - это мощный инструмент, который можно реализовать разными способами. Зная это, можно достичь полиморфного поведения с помощью:
Перегрузки функций
Шаблонов (функций и классов)
Переопределения методов в производных классах (с ограничениями)
Выбор подхода зависит от конкретных требований к производительности, гибкости и дизайну программы.