1. 多态编程的核心武器:虚函数与纯虚函数
在C++面向对象编程中,多态性是最具威力的特性之一。想象你正在开发一个图形编辑器,需要处理圆形、矩形、三角形等各种形状的绘制和计算。如果没有多态,你可能需要写一大堆if-else来判断对象类型,代码会变得臃肿且难以维护。这就是虚函数和纯虚函数大显身手的地方。
我曾在重构一个遗留系统时,将原本2000多行的条件分支代码通过多态优化到不足500行。虚函数表(vtable)的底层机制虽然会增加一点内存开销,但带来的设计灵活性绝对物超所值。让我们深入剖析这个支撑C++动态多态的核心机制。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 虚函数工作原理深度解析
2.1 虚函数表的内存布局
每个包含虚函数的类都会有一个隐藏的虚函数表指针(通常位于对象内存布局的首部)。当定义如下基类时:
cpp复制class Shape {
public:
virtual void draw() const { cout << "Drawing a shape" << endl; }
virtual double area() const = 0;
virtual ~Shape() {}
};
编译器会秘密完成以下工作:
- 为Shape类生成虚函数表
- 在每个Shape对象中添加_vptr指针
- 将虚函数地址按声明顺序存入虚表
通过这个简单的代码片段可以验证虚表的存在:
cpp复制Shape* s = new Circle();
cout << "对象地址:" << s << endl;
cout << "虚表地址:" << *(void**)s << endl;
注意:虚函数调用比普通成员函数多一次指针解引用和跳转,在性能敏感的循环中需谨慎使用
2.2 覆盖(override)与隐藏(hide)的陷阱
新手常混淆函数覆盖和隐藏的区别。看这个典型例子:
cpp复制class Base {
public:
virtual void foo(int) { cout << "Base::foo(int)" << endl; }
void bar() { cout << "Base::bar()" << endl; }
};
class Derived : pub
