面试题答案
一键面试虚函数动态绑定基本原理
在C++中,虚函数动态绑定是一种运行时多态的机制。当通过基类指针或引用调用虚函数时,实际调用的函数版本取决于指针或引用所指向的对象的实际类型,而非指针或引用本身的类型。
这一机制依赖于虚函数表(vtable)和虚函数表指针(vptr)。每个包含虚函数的类都有一个虚函数表,表中存放着该类所有虚函数的地址。每个对象都有一个虚函数表指针,该指针指向所属类的虚函数表。当通过基类指针或引用调用虚函数时,程序会根据对象的vptr找到对应的vtable,进而调用合适的虚函数版本。
代码示例及动态绑定发生情况
#include <iostream>
class Base {
public:
virtual void print() {
std::cout << "This is Base class" << std::endl;
}
};
class Derived : public Base {
public:
void print() override {
std::cout << "This is Derived class" << std::endl;
}
};
int main() {
Base* basePtr = new Base();
basePtr->print(); // 调用Base类的print函数
delete basePtr;
basePtr = new Derived();
basePtr->print(); // 动态绑定,调用Derived类的print函数
delete basePtr;
return 0;
}
在上述代码中:
- 虚函数声明:在
Base
类中,print
函数被声明为virtual
,这使得它成为虚函数。 - 函数重写:在
Derived
类中,print
函数使用override
关键字重写了Base
类的print
函数。override
关键字用于确保该函数确实重写了基类的虚函数,如果不小心写错函数签名,编译器会报错。 - 动态绑定发生:在
main
函数中,首先创建一个Base
类对象并通过Base
指针调用print
函数,此时调用的是Base
类的print
函数。然后创建一个Derived
类对象并将其地址赋给同一个Base
指针,再次调用print
函数,由于动态绑定机制,此时调用的是Derived
类的print
函数。
通过这种方式,C++实现了运行时多态,使得代码能够根据对象的实际类型调用合适的函数版本。