我想了解以下涉及虚拟函数的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;
}
答案 0 :(得分:0)
Here是对虚拟函数和vtable的很好的解释。
每个使用虚函数的类(或派生自使用虚函数的类)都被赋予自己的虚表
此表中的每个条目都只是一个函数指针,指向该类可访问的最衍生函数。
这几乎可以回答您的问题。
在第一个示例中,c
可访问的最派生函数是Car
的{{1}}。
第二个是foo
的{{1}}。在这里,即使您没有在Bmw
的{{1}}前面写foo
(这不是一种很好的编码样式),它的虚拟性还是继承自virtual
。 / p>
编辑:正如注释中正确说明的那样,vtables不是标准的一部分。有关更正式的说明,请参见this reference。
对于每个虚拟函数,都有最终的替代程序,该替代程序在进行虚拟函数调用时执行。基类Base的虚拟成员函数vf是最终的替代程序,除非派生类声明或继承(通过多次继承)另一个替代vf的函数。