【问题标题】:Dynamic binding, Static binding, Pointer to function, deep meaning动态绑定、静态绑定、函数指针、深层含义
【发布时间】:2020-04-24 03:46:25
【问题描述】:

在静态绑定中,要调用的方法是在编译时做出的,而在动态绑定中,要调用的方法是在运行时做出的。 使用动态绑定调用虚拟方法。 这意味着在编译阶段决定哪个是必须调用的虚拟表的函数指针。 作为一个函数指针,只不过是一个变量,它包含指向的函数的内存地址,并在编译时决定要调用哪个指针,在我看来,因此间接地决定了必须调用的方法在编译阶段。

所以我的问题是: 为什么说动态绑定是在执行过程中决定要调用的方法,而实际上在编译阶段就已经选择了虚拟表的入口?

【问题讨论】:

  • vtable 中的条目在编译时是已知的,但要查看的 vtable 仅在运行时才知道。
  • 当编译器看到这个函数并且bar 是虚拟的时考虑void (Foo& f) { f.bar();},它无法在编译时决定调用什么函数
  • 你不知道要看哪个表。
  • @Tony92,我真的不明白问题出在哪里。要调用虚方法,您必须间接调用vptr[index],其中index 在编译时已知,vptr 在运行时已知。 vptr[index] 在概念上与 *(vptr + index) 相同。即使您在编译时知道一个术语,您也不知道总和。这就是为什么它是动态绑定,而不是静态的。
  • Take a look。例如,对第三个虚函数的调用转换为call [rax+16],其中rax 是vtbl 指针(由构造函数初始化的第一个“隐藏”数据成员),16 是固定偏移量(= @987654332 @)。

标签: c++ binding polymorphism virtual-functions dynamic-binding


【解决方案1】:

静态绑定发生在调用函数所需的所有信息时 在编译时可用。 动态绑定发生在所有 函数调用所需的信息无法确定 编译时

这是动机,因为要调用的方法的决定是在运行时做出的。事实上,对于虚函数,编译器并不知道必须先调用哪个函数(它可能取决于调用该函数的类)。因此编译器链接虚拟表,但虚拟表可以根据对象的类指向不同的函数实现。这是编译器在编译时不知道的信息,只有在运行时才会部署。

如需更具体的细节,请留下一些有用的链接:

Difference between static and dynamic bindings

Early binding and Late binding

Virtual functions and Runtime Polimorphism

以这张图片为例:

如果您在参数是 class polygon 对象的函数中使用 class triangle 的实例化对象,则编译器不会先验地知道哪个真正的类是对象(如果是 Triangle 或 Rectangle )但在运行时如果您调用方法 area() 虚拟表指向类的正确方法。

【讨论】:

  • 我读过很多这种类型的文章,不幸的是,唯一的说法总是一样的:动态绑定->运行时决策静态绑定->编译时决策。但从来没有很好地解释这是如何发生的。我发布了这个问题以详细了解会发生什么。
  • 我添加一个例子来更好地解释这个概念
  • 好的,问题出在指向 vtable 的指针上,它是在运行时初始化的?
  • 我看过你的例子。
  • 编译器为每个类创建一个虚拟表。如果编译器事先不知道要调用的函数,则在运行时虚拟表指向正确的函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多