多态性 - C++中实现运行时多态的方式
一、概述
C++中的多态性是指同一个函数可以有多种不同的实现方式,并且在运行时根据实际情况进行选择执行。在C++中实现多态有两种方式:静态多态和动态多态。静态多态是指在编译时确定函数的实现,包括函数重载和模板函数;动态多态是指在运行时根据对象的实际类型来确定函数的实现,包括虚函数和抽象类。
二、静态多态
1、函数重载
函数重载是指在同一个作用域中定义多个同名函数,它们的参数列表不同。编译器会根据函数的参数列表唯一地确定要调用的函数。函数重载的实现可以通过编译时的函数匹配来实现,实现起来比较简单。 下面是一个函数重载的示例代码:
#include <iostream> void print(int i) { std::cout << "This is an integer: " << i << std::endl; } void print(float f) { std::cout << "This is a float: " << f << std::endl; } int main() { print(42); print(3.14f); return 0; }
上面的代码中,我们定义了两个同名的函数`print`,但是它们的参数列表不同,一个接受整数,一个接受浮点数。在调用函数`print`时,编译器会自动根据参数的类型选择调用哪个函数。
2、模板函数
模板函数是指在定义函数时使用了类型参数,可以让函数适用于多种不同的类型。编译器会在编译时根据参数类型来生成具体的函数实现。模板函数的实现可以通过编译时的模板实例化来实现。 下面是一个模板函数的示例代码:
#include <iostream> #include <cstdlib> template <typename T> T max(T a, T b) { return a > b ? a : b; } int main() { int x = 42, y = 23; float f = 3.14f, g = 2.71f; std::cout << "Max of " << x << " and " << y << " is " << max(x, y) << std::endl; std::cout << "Max of " << f << " and " << g << " is " << max(f, g) << std::endl; return 0; }
上面的代码中,我们定义了一个模板函数`max`,它可以针对整数、浮点数等多种类型进行运算。在调用函数`max`时,编译器会根据参数类型自动推断出要使用哪个具体的函数实现。
三、动态多态
1、虚函数
虚函数是指在基类中定义的函数可以被派生类重写的函数。通过将函数声明为虚函数,我们可以在运行时根据对象的实际类型来确定要调用的函数实现。在C++中,只要将函数声明为虚函数即可实现动态多态。 下面是一个虚函数的示例代码:
#include <iostream> class Shape { public: virtual float calculateArea() { return 0; } }; class Square : public Shape { public: Square(float l) : _length(l) {} virtual float calculateArea() { return _length * _length; } private: float _length; }; class Circle : public Shape { public: Circle(float r) : _radius(r) {} virtual float calculateArea() { return 3.14f * _radius * _radius; } private: float _radius; }; int main() { Shape *s1 = new Square(5); Shape *s2 = new Circle(3); std::cout << "Area of square is " << s1->calculateArea() << std::endl; std::cout << "Area of circle is " << s2->calculateArea() << std::endl; delete s1; delete s2; return 0; }
上面的代码中,我们定义了一个基类`Shape`和两个派生类`Square`和`Circle`,它们都实现了函数`calculateArea`。在调用函数`calculateArea`时,我们将基类指针指向派生类对象,可以看到运行时实际调用的是派生类的实现函数。
2、抽象类
抽象类是指包含至少一个纯虚函数的类,这个类不能被实例化,只能用作基类来派生出其他类。在C++中,可以通过将函数声明为纯虚函数来实现抽象类。 下面是一个抽象类的示例代码:
#include <iostream> class Shape { public: virtual float calculateArea() = 0; }; class Square : public Shape { public: Square(float l) : _length(l) {} virtual float calculateArea() { return _length * _length; } private: float _length; }; class Circle : public Shape { public: Circle(float r) : _radius(r) {} virtual float calculateArea() { return 3.14f * _radius * _radius; } private: float _radius; }; int main() { // Shape *s = new Shape(); // error: cannot instantiate abstract class Shape *s1 = new Square(5); Shape *s2 = new Circle(3); std::cout << "Area of square is " << s1->calculateArea() << std::endl; std::cout << "Area of circle is " << s2->calculateArea() << std::endl; delete s1; delete s2; return 0; }
上面的代码中,我们将基类`Shape`中的函数`calculateArea`声明为纯虚函数,从而实现了抽象类。抽象类不能被实例化,只能用作基类来派生出其他类。在调用函数`calculateArea`时,我们将基类指针指向派生类对象,可以看到运行时实际调用的是派生类的实现函数。
四、总结
本文介绍了C++中实现运行时多态的两种方式:静态多态和动态多态。静态多态包括函数重载和模板函数,动态多态包括虚函数和抽象类。通过对这些知识点的学习,可以更好地理解C++中的多态性,更灵活地应用在实际的程序开发中。
更新于:3个月前相关文章
- 【说站】java多态中成员如何访问
- 【说站】java多态的理解
- 【说站】java停止线程的方式
- 【说站】python导入类的不同方式
- 【说站】python列表排序的两种方式
- 【说站】php数组赋值方式
- 10个c#基础面试题和答案
- CSS overflow 内容溢出时的显示方式
- GET 和 POST 请求方式的区别
- Vue 的认识、特点介绍、安装方式
- js 遍历数组、对象的几种方式
- PHP 数组合并的几种方式
- PHP通过CURL的方式读取图片接口输出乱码
- TP5.0、TP5.1、TP6.0 下载方式及环境要求
- TP6.0 获取请求对象的五种方式
- Vue cli4 图片地址引入的几种方式
- Java导入Excel文件的实现方式
- Java执行Shell命令的方式
- Java创建数组的多种方式
- Java中的定时任务机制及实现方式详解