C/C++基础知识复习(41)

1) 什么是多态性?C++中如何实现多态?

多态性(Polymorphism)是面向对象编程中的一个重要特性,它允许不同的对象通过相同的接口表现出不同的行为。多态性使得程序能够根据对象的实际类型来决定调用哪个方法,而不是依赖于对象的静态类型。这种能力使得同一接口可以根据对象的不同类型有不同的实现,从而增加了系统的灵活性和扩展性。

C++ 中,多态性通过虚函数基类指针或引用来实现。具体分为两种类型:

  • 编译时多态(静态多态):通过函数重载(Function Overloading)和运算符重载(Operator Overloading)实现。编译器根据函数参数类型来决定调用哪个版本的函数。
  • 运行时多态(动态多态) :通过虚函数基类指针或引用来实现。对象的实际类型在运行时决定了调用哪个函数。
C++中实现运行时多态的步骤:
  1. 基类中声明一个虚函数(virtual)。
  2. 派生类重写基类中的虚函数。
  3. 使用基类指针或引用来调用虚函数。
例子:运行时多态
cpp 复制代码
#include <iostream> 
using namespace std; 
class Animal { public: // 虚函数 
virtual void sound() { 
cout << "Animal makes a sound" << endl; 
} }; 
class Dog : public Animal { 
public: // 重写基类的虚函数 
void sound() override { 
cout << "Dog barks" << endl; 
} }; 
class Cat : public Animal { public: // 重写基类的虚函数 
void sound() override { 
cout << "Cat meows" << endl; 
} }; 
int main() { 
Animal* animal1 = new Dog(); // 基类指针指向派生类对象 
Animal* animal2 = new Cat(); // 基类指针指向另一个派生类对象 
animal1->sound(); // 运行时多态,输出 
Dog barks animal2->sound(); // 运行时多态,输出 
Cat meows delete animal1; 
delete animal2; 
return 0; }

在这个例子中,sound 是一个虚函数。在 main 函数中,animal1animal2 是基类指针,指向不同类型的派生类对象(DogCat)。尽管使用的是基类指针,程序根据对象的实际类型来决定调用哪一个版本的 sound 函数,这就是运行时多态

2) 多态性的好处是什么?

  1. 提高代码的灵活性和可扩展性

    • 多态性使得相同的接口可以被不同的对象所实现,增强了代码的灵活性。例如,添加新的派生类时,只需要确保它重写基类中的虚函数,不需要修改其他代码。
  2. 简化代码维护

    • 通过多态性,代码可以通过统一的接口来操作不同的对象。这样,代码变得更加简洁,不需要对每种类型的对象写大量的条件判断语句。对于新的对象类型,只需要提供对应的实现,不需要修改调用代码。
  3. 实现动态绑定

    • 多态性允许在运行时根据对象的实际类型来决定调用哪一个函数。这种机制称为动态绑定,它使得程序能够根据不同的对象类型做出不同的决策,避免了静态绑定的限制。
  4. 实现接口统一

    • 通过多态性,可以实现接口的统一。在不同的类中定义相同的接口(如虚函数),然后由每个类提供不同的实现。调用者可以通过相同的接口与不同类型的对象交互,提高了代码的可维护性。
  5. 减少代码重复

    • 多态允许通过基类指针或引用来操作不同类型的对象,减少了大量重复的代码。这样可以避免为了支持不同类型而编写重复的函数或条件语句。
  6. 简化系统扩展

    • 在已有系统中,新增类型(比如新的派生类)时,不需要修改原有的代码,只需要提供新类型的具体实现即可。这使得系统具有很好的扩展性。
举例说明:

假设有一个图形绘制程序,支持不同类型的形状(如圆形、矩形、三角形等)。通过多态,可以使用统一的接口来绘制所有形状,而不需要为每个形状写不同的绘制代码。

cpp 复制代码
class Shape { 
public: virtual void draw() = 0; // 纯虚函数,强制派生类必须实现 
}; 
class Circle : public Shape { 
public: void draw() override { 
cout << "Drawing a Circle" << endl; 
} }; 
class Rectangle : public Shape { 
public: void draw() override { 
cout << "Drawing a Rectangle" << endl; 
} }; 
int main() { 
Shape* shapes[2]; shapes[0] = new Circle(); shapes[1] = new Rectangle(); 
for (int i = 0; i < 2; ++i) { 
shapes[i]->draw(); // 多态调用 
} 
delete shapes[0]; 
delete shapes[1]; 
return 0; 
}

输出:

cpp 复制代码
Drawing a Circle Drawing a Rectangle

在这个例子中,Shape 类有一个纯虚函数 draw,派生类 CircleRectangle 提供了不同的实现。通过多态性,shapes 数组可以存储不同类型的对象,并通过统一的接口 draw 来绘制它们。

总结

  • 多态性通过虚函数和基类指针/引用来实现,可以在运行时根据对象的实际类型来选择合适的方法执行,从而增加了代码的灵活性和可扩展性。
  • 多态性的好处包括提高代码的灵活性、简化代码维护、实现动态绑定、统一接口、减少代码重复、简化系统扩展等,尤其适用于大型系统和需要扩展的应用程序。
相关推荐
东风吹柳16 分钟前
观察者模式(sigslot in C++)
c++·观察者模式·信号槽·sigslot
嵌入式科普22 分钟前
十一、从0开始卷出一个新项目之瑞萨RA6M5串口DTC接收不定长
c语言·stm32·cubeide·e2studio·ra6m5·dma接收不定长
A懿轩A25 分钟前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
大胆飞猪2 小时前
C++9--前置++和后置++重载,const,日期类的实现(对前几篇知识点的应用)
c++
1 9 J2 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
夕泠爱吃糖2 小时前
C++中如何实现序列化和反序列化?
服务器·数据库·c++
长潇若雪2 小时前
《类和对象:基础原理全解析(上篇)》
开发语言·c++·经验分享·类和对象
仍然探索未知中3 小时前
C语言经典100例
c语言
爱吃西瓜的小菜鸡3 小时前
【C语言】矩阵乘法
c语言·学习·算法
染指11104 小时前
50.第二阶段x86游戏实战2-lua获取本地寻路,跨地图寻路和获取当前地图id
c++·windows·lua·游戏安全·反游戏外挂·游戏逆向·luastudio