【问题标题】:How vptr and vtable works in the bellow virtual related code?vptr 和 vtable 在下面的虚拟相关代码中是如何工作的?
【发布时间】:2019-11-25 11:47:24
【问题描述】:

据我所知,当我们在基类中创建一个虚拟函数时,编译器会创建一个可以称为 vptr 的指针,以及一个包含虚拟函数条目的 vtable,这些条目是此类的最新版本,以防被覆盖function .and vptr 指向 vtable。从基类派生的类具有相同的故事,它们有一个指针 vptr 和自己的 vtable,它保存最新的虚函数的条目。要了解我的问题,请遵循代码

#include <iostream>
using namespace std;
class base
{
public:
virtual void display(void)
{
    cout << "base\n";
}
};

class derived : public base
{
public:
void display(void)
{
    cout << "derived\n";
}
};
int main(void)
{
    base *p;
    base ob1;
    derived ob2;
    p=&ob2;
    p->display();//my point starts from here
    p->base::display();

}

在上面的代码中,语句 p->display(); 对象 p 点调用这个类的 vptr 并从 vtable 中查找显示函数并绑定它是有道理的。但我不明白我将如何描述语句 p->base::display();在vptr和vtable方面。编译器如何绑定基类版本的显示功能。因为派生类的vtable中不会有基类版本的显示功能。 如果我知道这里有什么不对的地方,请告诉我什么是对的。如果我是对的,那么告诉我如何描述 p->base::display();具有我描述的逻辑的语句 p->display();声明

【问题讨论】:

    标签: c++ virtual-functions vtable vptr


    【解决方案1】:

    但我不明白我将如何描述语句 p->base::display();在vptr和vtable方面,编译器如何绑定基类版本的显示功能

    Vptr 不以任何方式参与该调用。 Vptr 仅用于虚拟调度。

    在该调用中使用显式范围解析意味着您正在使用静态调度。您是说,无论对象参数的动态类型如何,都调用函数base::display


    虚拟分派是运行时多态的一种形式,也是面向对象编程的一个关键特性。虚拟分派函数调用时,调用将分派到继承层次结构中最派生的函数覆盖,这取决于对象的动态类型。

    相比之下,静态分派的函数调用是使用编译时名称解析来分派的,它不受对象的动态类型的影响。这是 C++ 中使用的默认调度类型。它通常也是命令式、非面向对象语言(如 C)中唯一的调度类型。

    虚拟调度只能与虚拟函数一起使用。虚拟调度通常使用虚拟函数表(vtable)和虚拟函数指针(vptr)来实现。

    【讨论】:

    • 感谢您的宝贵意见。如果您能描述一些有关虚拟调度和静态调度的意思,或者您可以建议我一些链接,以便我能明确回答我的问题,那就太好了跨度>
    • @S.M.TusharIbneSalam 我添加了对虚拟和静态调度含义的解释。至于链接,这应该对 C++ 基础有用:stackoverflow.com/questions/388242/…
    • 我认为虚拟调度和后期/动态绑定是指相同的。其实我对虚拟调度这个词并不熟悉。但是听说过后期绑定。毕竟,您的新答案为我的问题提供了更好的解决方案。现在我想我理解这件事了。
    猜你喜欢
    • 2012-04-21
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    相关资源
    最近更新 更多