当前位置: 首页 > news >正文

【C++】C++的多态是个啥,咋用的?

C++的多态是个啥,咋用的?

今天我来讲:多态(Polymorphism)。有人说它是面向对象的灵魂,那么,多态到底是个啥?怎么用?


一、多态是个啥?

“多态”这个词来自希腊语,意思是“多种形态”。放在编程世界里,就是:同一段代码,在不同的对象上,可以表现出不同的行为

举个例子,假设我们有一个 Animal 类,还有两个子类 DogCat

class Animal {
public:virtual void speak() {std::cout << "动物叫" << std::endl;}
};class Dog : public Animal {
public:void speak() override {std::cout << "汪汪" << std::endl;}
};class Cat : public Animal {
public:void speak() override {std::cout << "喵喵" << std::endl;}
};

如果写一段代码:

Animal* p1 = new Dog();
Animal* p2 = new Cat();p1->speak();  // 输出:汪汪
p2->speak();  // 输出:喵喵

你会发现,同样是 speak(),但是不同对象的表现不一样,这就是多态


二、多态分哪几种?

在 C++ 里,多态主要分两类:

  • 编译时多态(静态多态)
    例如函数重载、模板。这是在编译期就决定了调用哪个函数。
  • 运行时多态(动态多态)
    也就是我们常说的虚函数 + 继承。这是运行期根据对象的真实类型决定调用哪个函数。

今天我们重点聊 运行时多态,因为这是面向对象的核心。


三、多态的三个必要条件

想在 C++ 里实现运行时多态,需要满足三个条件:

  1. 有继承(基类和派生类)
  2. 基类方法是虚函数virtual 关键字)
  3. 通过基类指针或引用调用方法

比如:

Animal* p = new Dog();  // 基类指针指向派生类
p->speak();             // 发生多态

如果不用 virtual,就没有多态,调用的永远是 Animal 里的 speak()


四、底层虚函数表(vtable)!

为什么 C++ 能在运行时决定调用哪个函数?
答案是 虚函数表机制(Virtual Table)

编译器在处理含有虚函数的类时,会做几件事:

  1. 为每个含虚函数的类生成一张 虚函数表(vtable),里面存放该类的虚函数地址。
  2. 在对象里存一个 虚表指针(vptr),指向对应类的虚表。
  3. 当你调用虚函数时,编译器会通过 vptr 查虚表,找到正确的函数地址再执行。

简化后的示意图:

Animal 对象:
[vptr] -> [Animal::speak]Dog 对象:
[vptr] -> [Dog::speak]

所以,p->speak() 运行时调用哪一个函数,取决于 vptr 指向哪张虚表。


性能影响大吗?

虚函数调用需要一次额外的指针间接寻址,比普通函数慢一点,但代价很小。

放心用吧,你电脑撑得住~


五、用多态的正确姿势

1. 析构函数要是虚的

如果基类用指针指向派生类对象,那么基类析构函数必须是虚函数,否则会内存泄漏。

class Animal {
public:virtual ~Animal() {}  // 一定要 virtual!!!
};

如果不用 virtualdelete p 时只会调用基类析构函数,派生类资源不会释放。


2. 避免 slicing(对象切片)

如果你用值传递,而不是指针或引用,多态会失效。

Dog d;
Animal a = d;  // 切片:只拷贝 Animal 部分
a.speak();     // 输出“动物叫”

3. 多态和模板结合

C++ 的 模板 + 多态 结合非常强大,可以做到编译时多态 + 运行时多态配合,用在策略模式、插件系统等场景。


六、总结~

C++ 的多态就是运行时根据对象的实际类型,动态决定调用哪个方法,它通过 虚函数表 实现,是面向对象编程的核心特性之一。

正确使用多态可以让代码更灵活、更易扩展,但也要注意析构、性能和设计合理性。

http://www.dtcms.com/a/431636.html

相关文章:

  • 【Linux 系统】进程状态
  • 搜索引擎网站排行榜广州seo优化公司排名
  • 【强化学习】#8 DQN(深度Q学习)
  • 【原创】SpringBoot3+Vue3学生信息管理系统
  • Linux查看日志方法
  • 个人签名设计网站服装网站策划设计
  • 《Span-based Localizing Network for Natural Language Video Localization》
  • VRRP上行逃生:两种核心方案详解
  • 方法的调用:递归
  • 设计师常用的灵感网站做网站怎么盈利
  • 工程承包网站哪个好?临汾工程建设招标投标网站
  • 从新疆油田数据采集器,看Digi ZigBee模块在石油行业上的应用
  • C语言指针与字符串详解
  • 全长抗体表达:从载体策略到产业化,如何实现高活性抗体的高效生产?
  • 0.3 神经网络学习率、激活函数、损失函数
  • 最全的ppt模板网站舆情监测系统永久免费
  • MySQL通过二进制日志恢复数据
  • 建立网站专业公司吗wordpress 换主题问题
  • 高功耗显卡装机实战:电源 / 机箱 / 主板兼容问题全解析与解决方案
  • Java 性能监控与分析工具
  • 写作网站六大神书wordpress改小程序
  • 网站没建设可以访问吗最流行的网站开发
  • 【图像理解进阶】微调Qwen2.5-VL-32B用于遥感图像理解:从硬件到代码实践
  • 比较有名的diy制作网站wordpress category_name
  • 利用视觉对齐的文本洞察进行医学图像分割
  • 定西兰州网站建设做公司简介需要多少钱
  • 网站icp备案查不到兼职做调查哪个网站好
  • 【C++】透视C++多态:从虚函数表到底层内存布局的完全拆解
  • PSG技术分析:战术体系与关键角色
  • 在线做视频的网站重庆装修公司电话