虚函数与 vtable
使用虚函数实现运行时多态,并了解 vtable 的概念
虚函数与 vtable 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。
静态绑定与动态绑定
默认情况下,成员调用采用静态绑定——编译器根据声明类型选择函数。使用 virtual 函数时,调用会根据实际类型进行动态绑定。
声明虚函数
在基类中为函数标记 virtual。派生类可以重写它。
class Shape {
public:
virtual double area() const = 0; // pure virtual
virtual ~Shape() = default;
};
class Circle : public Shape {
double r_;
public:
Circle(double r) : r_(r) {}
double area() const override { return 3.14159 * r_ * r_; }
};override 说明符
请将 override 添加到派生类方法中。编译器会验证该函数确实重写了虚函数,从而捕获签名中的拼写错误。
终止重写说明符
final 可以阻止进一步重写。请将它用于不应被继承的类,或不应再次被重写的方法。
class Concrete final : public Base { /* ... */ };
class Base {
virtual void f() final; // cannot be overridden
};通过 Base 指针调用
这就是多态的妙处:基类指针可以分派到正确的派生类方法。
Shape* s = new Circle(3.0);
std::cout << s->area(); // 28.27... (Circle::area)
delete s;虚函数表概念
每个多态类都有一个隐藏的虚函数表——其中存放着函数指针。每个对象都持有一个隐藏指针(虚表指针),指向其所属类的虚函数表。
虚函数调用的开销
虚函数调用需要通过虚函数表进行一次额外的间接寻址。在大多数代码中,这种开销可以忽略不计。如果经过测量发现它成为瓶颈,请避免在内部循环中使用。
纯虚函数
在函数后追加 = 0,即可将其声明为纯虚函数。派生类必须重写它才能被实例化。此时该类会变成抽象类。
虚析构函数
如果类包含任何虚函数,或需要通过基类指针删除,请为它提供虚析构函数。否则,派生类析构函数将永远不会运行。
class Base {
public:
virtual ~Base() = default; // safe to delete through Base*
};使用智能指针实现多态
请通过指向基类的智能指针持有多态对象。智能指针会正确处理对象的销毁。
std::unique_ptr<Shape> s = std::make_unique<Circle>(3.0);再谈对象切片
将派生类对象按值传递给期望基类的函数时,派生部分会被切掉。对于多态参数,请使用引用或指针。
性能权衡
虚函数以较小的运行时开销换取了灵活性。模板提供了没有运行时开销的编译期多态——请根据是否需要运行时多态来选择。
快速检查
为什么多态基类应当拥有 virtual 析构函数?
总结
虚函数通过每个类的虚函数表实现运行时多态。请使用 override 标记重写,并使用 final 阻止进一步继承。多态基类始终应当拥有虚析构函数。
常见问题解答
「虚函数与 vtable」课时是免费的吗?
是的 — 「虚函数与 vtable」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。
「虚函数与 vtable」这节课中我会学到什么?
使用虚函数实现运行时多态,并了解 vtable 的概念 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C++ Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「虚函数与 vtable」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C++ Academy 课中编写并运行代码吗?
能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。