协程和多态

协程

实现关键:栈、状态、上下文切换、调度器

协程(Coroutines)底层实现的原理通常涉及到以下四个关键概念:栈,状态,上下文切换和调度器。 这里我们主要讨论这些概念的基础知识,并不会过多涉及到特定编程语言的实现。

  1. 栈: 每个线程都有自己的栈,用于存储函数调用的上下文。相反,协程共享同一个线程,因此协程需要有自己的栈或者栈帧。这个栈或者栈帧用于在上下文切换时保存协程的状态。

  2. 状态: 每个协程维护它自己的运行状态。最基础的两个状态是“运行中”和“挂起”。协程能够在这两个状态之间自由切换。

  3. 上下文切换: 这是协程中一个最关键的概念。当一个协程挂起时,运行的控制权需要被移交给其他协程或者调度器。在这个过程中,需要保存当前协程的状态,并且恢复下一个协程的状态。这就叫做上下文切换。

  4. 调度器: 这是实现协程的另一个关键组件。当一个协程挂起时,需要有一个调度器来决定下一个要运行的协程是哪一个。

在实际实现中,协程的底层机制会和具体使用的编程语言和平台有关。例如,Python 的 asyncio 库就是通过生成器这一语言特性来实现协程的:生成器可以保存自己的状态,因此每一个生成器就可以被看作一个协程。当运行到 yield 表达式时,生成器会暂停,这就相当于协程的挂起。另外,asyncio 还提供了一个事件循环,可以作为协程的调度器,用来控制协程的执行顺序。

多态

开销:

空间消耗 --》虚函数表【数组,子类copy父类并覆盖重写函数】(虚函数个数*4bytes)、虚函数指针(4bytes)

时间消耗 --》寻找函数地址消耗

存储:

虚函数表(vtable)在静态存储区,虚函数指针在对象开始位置的4bytes

创建:

子类会copy父类的虚函数表,并用新地址覆盖重写函数地址

C++中的虚函数是用来实现运行时多态的主要机制。使用虚函数会带来一些开销,主要包括以下几个方面:

  1. 存储开销: 每一个含有虚函数的类(或者从含有虚函数的类派生出来的类)的对象在内存中都会有一些额外的存储开销。因为这些对象需要存储一个指向虚函数表(vtable,或虚函数指针表)的指针。虚函数表是一个存储指向类的虚函数的指针的数组。

  2. 内存开销: 虚函数表是静态的,它对于某个类的所有对象都是相同的。这意味着,即使你创建了很多某个类的对象,虚函数表只会有一份。但是,如果你有很多包含虚函数的类,那么每个类都有一份虚函数表,这就会占用一些内存。

  3. 时间开销: 如果一个函数被声明为虚函数,那么调用这个函数将可能需要额外的时间开销。因为调用虚函数需要通过虚函数表,并且可能需要进行一次间接寻址。在需要高性能的情况下,这可能成为一个问题。

  4. 二进制代码大小开销: 生成虚函数表会增加二进制代码的大小。

这些开销通常是可以接受的,因为虚函数提供了强大的功能:运行时多态。它们允许你写出更通用、更易于扩展的代码。然而,在某些性能敏感或资源受限的情况下,这些开销可能需要被考虑进去。因此,当设计一个类的时候,需要根据情况来决定是否需要使用虚函数。

C++虚函数表(vtable)是存储在对象的内存空间的,但这个位置不是作为对象的正常数据成员,而是隐藏的额外成员。每一个包含虚函数的类或者子类的对象,都会在内存布局的开始位置,保留一个指向虚函数表的指针,这个指针通常叫做vptr。可执行文件在执行时,它们的vtable放在静态存储区里,这样所有的对象都可以共享这些vtable。

例如,你创建一个派生对象(包含虚函数)的时候,这个对象在内存中的布局通常是这样的:

  1. 在对象内存布局的开始位置是一个指向虚函数表的指针(vptr)。

  2. 紧接着是派生类继承的基类的数据成员(如果有的话)。

  3. 然后是派生类自身的数据成员。

值得注意的是,C++的标准并没有指定虚函数表应该如何实现,这依赖于具体的编译器和对象模型。虚函数表的实现和存储位置可能因编译器和平台的不同而不同。所以,在跨平台开发,甚至是不同编译器间,对虚函数表的直接操作或假设,都可能导致程序的不兼容。

在C++中,当一个类(称为子类或派生类)从另一个类(称为基类)派生,并重写(覆盖)了基类的虚函数时,编译器会在子类的虚函数表(vtable)中为该函数生成一个新的条目。

基类的虚函数表中,每一个函数都有一个指向实现这个函数的代码的指针。当子类重写了这个函数,编译器会生成一个新的函数实现,并且在子类的虚函数表中,将这个函数的条目改为指向新的实现。

当你通过一个指向子类对象的基类指针调用这个虚函数时,运行时系统会根据存储在对象中的虚函数表指针(vptr)找到子类的虚函数表,然后调用表中对应函数的新的实现,实现运行时多态。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

love_0_love

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值