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 来绘制它们。

总结

  • 多态性通过虚函数和基类指针/引用来实现,可以在运行时根据对象的实际类型来选择合适的方法执行,从而增加了代码的灵活性和可扩展性。
  • 多态性的好处包括提高代码的灵活性、简化代码维护、实现动态绑定、统一接口、减少代码重复、简化系统扩展等,尤其适用于大型系统和需要扩展的应用程序。
相关推荐
Ritsu栗子8 分钟前
代码随想录算法训练营day35
c++·算法
好一点,更好一点18 分钟前
systemC示例
开发语言·c++·算法
卷卷的小趴菜学编程39 分钟前
c++之List容器的模拟实现
服务器·c语言·开发语言·数据结构·c++·算法·list
年轮不改39 分钟前
Qt基础项目篇——Qt版Word字处理软件
c++·qt
玉蜉蝣1 小时前
PAT甲级-1014 Waiting in Line
c++·算法·队列·pat甲·银行排队问题
半盏茶香3 小时前
扬帆数据结构算法之雅舟航程,漫步C++幽谷——LeetCode刷题之移除链表元素、反转链表、找中间节点、合并有序链表、链表的回文结构
数据结构·c++·算法
哎呦,帅小伙哦3 小时前
Effective C++ 规则41:了解隐式接口和编译期多态
c++·effective c++
DARLING Zero two♡4 小时前
【初阶数据结构】逆流的回环链桥:双链表
c语言·数据结构·c++·链表·双链表
9毫米的幻想4 小时前
【Linux系统】—— 编译器 gcc/g++ 的使用
linux·运维·服务器·c语言·c++
Cando学算法4 小时前
Codeforces Round 1000 (Div. 2)(前三题)
数据结构·c++·算法