真实面经题目 · 原创解析

虚函数和纯虚函数有什么区别?

虚函数用于运行期多态,纯虚函数用于定义必须由派生类实现的抽象接口。回答要区分语法、是否可实例化、默认实现、虚表机制和析构函数场景。

出现于:拼多多 · C/C++

60 秒回答模板

虚函数是在基类中用 virtual 声明、允许派生类 override 的成员函数,用基类指针或引用调用时会发生动态绑定。纯虚函数是在声明后写 = 0,表示这个类提供抽象接口,包含纯虚函数的类是抽象类,不能直接实例化,派生类必须实现所有纯虚函数后才能实例化。纯虚函数也可以有函数体,但语义上仍要求派生类提供实现。两者底层都依赖虚表和虚指针,常见追问是为什么基类析构函数要声明为 virtual。

考点 虚函数允许覆盖
难度 真实面经题
回答目标 讲清方法、取舍和追问

深入解析

01

虚函数做多态

虚函数让基类接口在运行期根据真实对象类型分发到派生类实现。典型场景是用 Base* 或 Base& 操作不同子类对象,调用同名接口时执行各自逻辑。

02

纯虚函数做接口

纯虚函数用 = 0 声明,表达这个函数在基类层面没有完整实现或必须由子类定义。只要类里还有未实现纯虚函数,这个类就是抽象类,不能创建对象。

03

实例化规则不同

含普通虚函数的类可以实例化,除非还有纯虚函数。含纯虚函数的抽象类不能直接实例化,派生类必须覆盖所有纯虚函数后才成为具体类。

04

默认实现不同

普通虚函数通常有默认实现,派生类可覆盖也可不覆盖。纯虚函数也能在类外提供函数体,但它仍然是纯虚函数,主要用于给派生类显式调用公共逻辑。

05

底层机制相同

虚函数和纯虚函数都会进入虚表,运行期通过对象的虚指针找到实际函数地址。区别不在派发机制,而在接口约束和类是否抽象。

易错点

  • 不要说纯虚函数一定没有实现,它可以有函数体,但语义仍是抽象接口。
  • 不要说虚函数只能用指针调用,引用调用同样能触发动态绑定。
  • 不要忽略抽象类不能实例化这个规则。
  • 不要漏掉虚析构,C++ 多态题经常追问资源释放。

面试官追问

纯虚函数能不能有实现?

可以在类外提供实现,但它仍然是纯虚函数,类仍然抽象;派生类可以在自己的实现中显式调用这个基类实现。

构造函数能不能是虚函数?

不能。对象构造期间虚表和派生部分还没有完整建立,构造函数不能依赖运行期多态。

为什么析构函数常声明为虚函数?

如果通过基类指针删除派生对象,虚析构能保证先执行派生类析构,再执行基类析构,避免资源泄漏。