【问题标题】:Explanation of the output of the C++ code involving virtual function涉及虚函数的C++代码输出说明
【发布时间】:2019-08-31 10:42:03
【问题描述】:

我想了解以下涉及虚函数的 C++ 程序的输出背后的原因。还请说明以下两种情况下如何生成函数指针表和包含指向函数指针表的链接的虚拟指针表,以及在运行时如何解析调用。

/******* PROGRAM 1 *******/
#include <iostream>
using namespace std;

class Car {
    public:
    virtual void foo() {
        cout<<"Car"<<endl;
    }
};

class Bmw: public Car {
    public:
    void foo1() {
        cout<<"Bmw"<<endl;
    }
};

int main() {
        Car *c = new Bmw(); 

        c->foo();           // gives output Car even though foo() 
                            //function does not exist in BMS class. 

        return 0;
}

/******* PROGRAM 2 *******/
#include<iostream>
using namespace std;

class Car {
    public:
    virtual void foo() {
        cout<<"Car"<<endl;
    }
};

class Bmw: public Car {
    public:
    void foo() {
        cout<<"Bmw"<<endl;
    }
};

class Bmw7: public Bmw {
    public:
    void foo1(){
        cout<<"Bmw7"<<endl;
    }
};

int main() {
    Car *c = new Bmw7();

    c->foo();       //gives output Bmw. Why output is not Car ??
    return 0;
}

【问题讨论】:

  • foo1 不是foo。您可能会发现 override 很有帮助
  • 您也不妨咨询this list。没有什么比一本经过审查的好书更能帮助人们理解像 C++ 这样的复杂语言了。
  • @user4581301 你为什么不认为这是一个答案?
  • @Yunnosch 在我看来太像错字了。如果不是,那么“标识符必须匹配”对未来的程序员来说没有多大价值。如果您不知道您已经达到 Stack Overflow 的计时器,那么您的参考资料充其量是狡猾的。
  • @user4581301 问题中给出的上述代码 sn-p 中没有错字。我在 Arcesium 的采访中被问到这个问题,但无法做到。我被拒绝了,在那之后我做的第一件事就是在这里发布这个问题。 2年过去了,我目前在Arcesium的母公司D.E.工作。 Shaw,作为 C++ 开发人员 (SDE-II)。接受的答案和所有 cmets 现在对我来说非常有意义。

标签: c++ oop inheritance polymorphism virtual-functions


【解决方案1】:

Here 很好地解释了虚函数和虚表。

每个使用虚函数的类(或派生自使用虚函数的类)都有自己的虚表

此表中的每个条目只是一个函数指针,指向该类可访问的最衍生函数。

这几乎可以回答您的问题。 在第一个示例中,c 可访问的最衍生函数是Carfoo。 第二个是Bmwfoo。这里即使Bmw中的foo前面没有写virtual(这不是一个很好的编码风格),它的虚拟性还是继承自Car

编辑:正如评论中正确说明的那样,vtables 不是标准的一部分。更正式的解释见this reference

对于每个虚函数,都有一个最终的覆盖器,它在进行虚函数调用时执行。基类 Base 的虚成员函数 vf 是最终的覆盖器,除非派生类声明或继承(通过多重继承)另一个覆盖 vf 的函数。

【讨论】:

  • 注意:C++ 不需要使用 VTable。 VTables 是迄今为止最常见的实现,因为它以直接且相对容易实现的方式完成工作,因此您最有可能看到它。与此同时,在世界各地的秘密实验室中,顶尖科学家正在研究替代方案,并一直在寻找更好的解决方案。
  • 谢谢,是的,刚刚提供了这个答案,因为问题是专门关于 vtable 的。已编辑。
猜你喜欢
  • 2017-05-03
  • 2011-01-03
  • 1970-01-01
  • 1970-01-01
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-14
相关资源
最近更新 更多