版权声明:允许转载,请注明文章出处 https://blog.csdn.net/Vickers_xiaowei/article/details/86556998
文章目录
两个深入理解虚函数的面试题
1、 对象访问普通函数快还是虚函数更快?答:首先如果是普通对象,是一样快的。如果是指针对象或者是引用对象,则调用的普通函数快,因为构成多态,运行时调用虚函数需要到虚函数表中去查找。
为什么普通对象调用普通函数和虚函数是一样快的?
#include<iostream>
using namespace std;
class Person {
public:
virtual void BuyTicket() { cout << "Virtual BuyTicket" << endl; }
void SaleTicket()
{
cout << "NonVirtual SaleTicket" << endl;
}
};
int main()
{
Person p;
p.BuyTicket(); //对象访问虚函数
p.SaleTicket(); //对象访问普通函数
system("pause");
return 0;
}
这里我们看到,对象在去调用虚函数和普通函数的时候,都是直接call对象的成员函数,也就是说,虚函数这样用,它就没有意义,与普通函数一样。
为什么对象指针/引用调用普通函数比调用虚函数快?
为了让大家体验对象指针调用虚函数时候的查找过程,我又增加了两个虚函数。
#include<iostream>
using namespace std;
class Person {
public:
virtual void BuyTicket1() { cout << "Virtual BuyTicket1" << endl; }
virtual void BuyTicket2() { cout << "Virtual BuyTicket2" << endl; }
virtual void BuyTicket3() { cout << "Virtual BuyTicket3" << endl; }
void SaleTicket()
{
cout << "NonVirtual SaleTicket" << endl;
}
};
void Func(Person *p)
{
(*p).BuyTicket3();
(*p).SaleTicket();
}
int main()
{
Person p;
Func(&p);
system("pause");
return 0;
}
正因为对象对象指针调用虚函数时候需要到虚函数表去查找虚函数,所以,指针调用虚函数比普通函数慢。
2、虚函数表是在什么阶段生成的,存在哪的?答:虚函数是在编译阶段就生成的,一般情况下存在代码段的。
看看虚函数到底存在哪里?有些说数据段?有些人说代码段?
#include<iostream>
using namespace std;
class Person {
public:
virtual void BuyTicket() { cout << "Virtual BuyTicket1" << endl; }
};
int main()
{
int a = 0; //栈
int* b = new int; //*b存在堆
static int c = 0; //数据段
char* ptr = "Hello World"; //*ptr存储在代码段
Person p;
cout << "Virtual---->"<<*(int*)&p<< endl;
cout << "a---->"<<&a << endl;
cout << "b---->" << &(*b) << endl;
cout << "c---->" << &c << endl;
printf("ptr---->%p\n", &(*ptr));
system("pause");
return 0;
}
我们看到看到只有这个虚函数是负数,跟它最近的是最小的整数000FDC94,也就是说虚函数存储在代码段。
联编
动态联编 和 静态联编 都是多态性的一种体现。
1.静态绑定又称为前期绑定(早绑定),在程序编译期间确定了程序的行为,也称为静态多态,比如:函数重载。
2. 动态绑定又称后期绑定(晚绑定),是在程序运行期间,根据具体拿到的类型确定程序的具体行为,调用具体的函数,也称为动态多态。