一、C++多态性
1、组成
(1)编译时多态性(静态多态性)。
(2)运行时多态性(动态多态性)。
二、编译时多态性
1、组成
(1)函数重载(示例1)
需具备条件:
a.方法具有相同的函数名。
b.方法具有不同的参数列表(参数数量、参数类型、参数顺序有一项或多项有区别)。
c.方法具有相同的返回值类型。
(2)函数重写(示例2)
需具备条件:
a.方法具有相同的函数名。
b.方法具有相同的参数列表(参数数量、参数类型、参数顺序一致)。
c.方法具有相同的返回值类型。
(3)模板(示例3、示例4)
通用的函数或者类,根据所传递的参数类型和数量来生成特定的函数或类。
2、特点
(1)编译时确定调用哪个函数或实例化哪个模板。
三、运行时多态性
1、组成
(1)虚函数和继承(示例5)
虚函数是在基类中声明的,可以被派生类重写。当基类指针或引用调用虚函数时,会根据指针和引用所指向的实际对象类型来决定调用哪个版本的虚函数。
2、特点
(1)运行时基于对象的实际类型来确定调用哪个函数。
四、代码示例
示例1:函数重载。
#include <iostream>
#include <string>
// 重载函数:计算两个整数的和
int add(int a, int b) {
return a + b;
}
// 重载函数:计算三个整数的和
int add(int a, int b, int c) {
return a + b + c;
}
// 重载函数:连接两个字符串
std::string add(const std::string& str1, const std::string& str2) {
return str1 + str2;
}
int main() {
int sum2 = add(2, 3); // 调用第一个重载函数
int sum3 = add(1, 2, 3); // 调用第二个重载函数
std::string result = add("Hello, ", "world!"); // 调用第三个重载函数
std::cout << "Sum of 2 and 3: " << sum2 << std::endl;
std::cout << "Sum of 1, 2, and 3: " << sum3 << std::endl;
std::cout << "Concatenated string: " << result << std::endl;
return 0;
}
示例2:函数重写。
#include <iostream>
// 基类
class Base {
public:
// 虚函数
virtual void show() const {
std::cout << "Base class show function called." << std::endl;
}
// 虚析构函数,确保正确释放派生类对象
virtual ~Base() {}
};
// 派生类
class Derived : public Base {
public:
// 重写基类的虚函数
void show() const override {
std::cout << "Derived class show function called." << std::endl;
}
};
int main() {
// 创建基类对象
Base base;
// 创建派生类对象
Derived derived;
// 调用基类的show函数
base.show();
// 调用派生类的show函数
derived.show();
// 通过基类指针调用派生类的show函数(多态性)
Base* basePtr = &derived;
basePtr->show();
return 0;
}
示例3:类模板。
#include <iostream>
// 类模板定义
template <typename T>
class Box {
private:
T data;
public:
Box(T d) : data(d) {}
T getData() const {
return data;
}
void setData(T d) {
data = d;
}
};
int main() {
// 使用int类型实例化Box类模板
Box<int> intBox(123);
std::cout << "Int Box: " << intBox.getData() << std::endl;
// 使用double类型实例化Box类模板
Box<double> doubleBox(456.78);
std::cout << "Double Box: " << doubleBox.getData() << std::endl;
return 0;
}
示例4:函数模板。
#include <iostream>
// 类模板定义
template <typename T>
class Box {
private:
T data;
public:
Box(T d) : data(d) {}
T getData() const {
return data;
}
void setData(T d) {
data = d;
}
};
int main() {
// 使用int类型实例化Box类模板
Box<int> intBox(123);
std::cout << "Int Box: " << intBox.getData() << std::endl;
// 使用double类型实例化Box类模板
Box<double> doubleBox(456.78);
std::cout << "Double Box: " << doubleBox.getData() << std::endl;
return 0;
}
示例5:虚函数。
#include <iostream>
// 基类
class Animal {
public:
// 虚函数,发出声音
virtual void makeSound() const {
std::cout << "Animal makes a sound." << std::endl;
}
// 纯虚函数,移动方式
virtual void move() const = 0;
// 虚析构函数,确保派生类对象被正确销毁
virtual ~Animal() {}
};
// 派生类:狗
class Dog : public Animal {
public:
// 重写基类的虚函数:发出声音
void makeSound() const override {
std::cout << "Woof! Woof!" << std::endl;
}
// 实现基类的纯虚函数:移动方式
void move() const override {
std::cout << "Dog runs." << std::endl;
}
};
// 派生类:猫
class Cat : public Animal {
public:
// 重写基类的虚函数:发出声音
void makeSound() const override {
std::cout << "Meow! Meow!" << std::endl;
}
// 实现基类的纯虚函数:移动方式
void move() const override {
std::cout << "Cat walks." << std::endl;
}
};
int main() {
// 创建派生类对象
Dog dog;
Cat cat;
// 创建指向派生类对象的基类指针数组
const Animal* animals[] = { &dog, &cat };
// 通过基类指针数组调用虚函数和纯虚函数,展示多态性
for (const Animal* animal : animals) {
animal->makeSound(); // 调用虚函数
animal->move(); // 调用纯虚函数
}
return 0;
}