【C/C++】虚函数
📘 C++ 虚函数详解(Virtual Function)
📌 什么是虚函数?
虚函数(Virtual Function) 是 C++ 中实现运行时多态(Runtime Polymorphism) 的核心机制。
它允许派生类 重写(Override) 基类的函数实现,使得通过基类指针或引用调用函数时,能根据对象的实际类型动态绑定到对应的实现。
🔧 虚函数的作用
作用 | 说明 |
---|---|
实现多态性 | 允许基类指针/引用指向派生类对象,并调用派生类的方法 |
接口设计 | 基类定义接口(纯虚函数),派生类实现具体功能 |
解耦代码 | 业务逻辑与具体实现分离,提高代码可维护性 |
🛠️ 使用方式
1. 声明虚函数
class Base {
public:virtual void show() { std::cout << "Base class" << std::endl; }
};
2. 派生类重写虚函数
class Derived : public Base {
public:void show() override { // C++11 强制重写检查std::cout << "Derived class" << std::endl;}
};
3. 通过基类指针/引用调用
Base* ptr = new Derived();
ptr->show(); // 输出 "Derived class"
⚠️ 虚析构函数
当基类可能被继承时,必须将析构函数声明为虚函数,防止内存泄漏:
class Base {
public:virtual ~Base() {} // 虚析构函数
};
🧠 虚函数表(vtable)与虚函数指针(vptr)
- 虚函数表(vtable):每个含虚函数的类都有一个虚函数表,存储虚函数的地址。
- 虚函数指针(vptr):每个对象隐式包含一个指向其类虚函数表的指针。
⚠️ 底层机制无需手动干预,但理解原理有助于优化设计。
⚖️ 注意事项
限制项 | 说明 |
---|---|
不能是静态函数 | 静态函数属于类而非对象,无法动态绑定 |
不能是友元函数 | 友元函数不属于类成员 |
默认参数值需谨慎 | 默认参数在编译时绑定,可能引发意外行为 |
性能开销 | 间接寻址调用,比普通函数慢 5-10 倍 |
📦 示例代码
#include <iostream>
using namespace std;class Shape {
public:virtual void draw() { cout << "Shape" << endl; }virtual ~Shape() {} // 虚析构函数
};class Circle : public Shape {
public:void draw() override { cout << "Circle" << endl; }
};class Rectangle : public Shape {
public:void draw() override { cout << "Rectangle" << endl; }
};int main() {Shape* shapes[] = { new Circle(), new Rectangle() };for (auto s : shapes) {s->draw(); // 多态调用delete s;}return 0;
}
输出结果:
Circle
Rectangle
❓ 常见问题
问题 | 回答 |
---|---|
虚函数可以是 inline 吗? | ✅ 可以声明为 inline ,但编译器会忽略 inline 优化 |
虚函数可以有默认参数吗? | ✅ 可以,但建议保持参数一致以避免混淆 |
构造函数可以是虚函数吗? | ❌ 不可以,构造期间对象类型未完全确定 |
虚函数可以是模板函数吗? | ❌ 不支持虚模板函数,但可以有虚函数模板特化 |
🔒 纯虚函数与抽象类
纯虚函数 是没有实现的虚函数,用于定义接口:
class Interface {
public:virtual void method() = 0; // 纯虚函数
};
- 包含纯虚函数的类称为抽象类,不能直接实例化。
- 派生类必须实现所有纯虚函数,否则自身也是抽象类。
📊 总结
核心要点 | 说明 |
---|---|
多态性 | 通过虚函数实现运行时动态绑定 |
接口设计 | 纯虚函数定义接口,派生类实现细节 |
性能考量 | 虚函数调用有间接寻址开销 |
安全销毁 | 基类析构函数必须为虚函数 |
设计原则 | 对扩展开放,对修改关闭(OCP) |
📝 设计建议
📌 设计建议:
- 仅对需要多态的函数使用
virtual
。 - 抽象类作为接口时,析构函数必须为虚函数。
- 使用
override
显式标记重写函数(C++11 起)。
✅ 术语对照:
- Virtual Function → 虚函数
- Pure Virtual Function → 纯虚函数
- Abstract Class → 抽象类
- Runtime Polymorphism → 运行时多态