尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

不要在构造函数或析构函数中调用虚函数

不要在构造函数或析构函数中调用虚函数
📅 发布时间:2026/6/17 19:24:06

在构造和析构期间,虚函数机制会“降级”为静态绑定。

为了更透彻地理解这一点,我们需要从对象的生命周期和虚函数指针(vptr)的演变来深入探讨。


1. 核心原理:对象身份的演变

在 C++ 中,一个派生类对象的构造过程就像是一场“身份的进化”。

构造阶段(从下往上建):

  1. 第一步:分配内存。
  2. 第二步:调用基类构造函数。此时,对象的 vptr(虚函数指针)指向的是基类的虚函数表(Vtable)。此时编译器认为这个对象就是一个基类对象。
  3. 第三步:基类构造完成,开始执行派生类构造函数。此时,vptr 会被更新,指向派生类的虚函数表。

结论:当你在基类构造函数里调用虚函数时,派生类部分还是一片虚无(未初始化),为了安全,C++ 禁止此时访问派生类成员,因此只调用基类版本。


2. 析构阶段:身份的“倒退”

析构过程正好相反,是一场“身份的退化”。

  1. 第一步:执行派生类析构函数。
  2. 第二步:派生类部分销毁完毕,vptr 重新指向基类的虚函数表。
  3. 第三步:执行基类析构函数。此时,对象的派生类特有成员已经不存在了。

结论:在基类析构函数执行时,对象已经不再是一个“派生类对象”了,它退化成了一个纯粹的基类对象。


3. 危险后果:纯虚函数崩溃

如果你在基类构造函数中调用了一个纯虚函数(没有给出实现的),后果将是灾难性的。

class Base {
public:Base() { log(); }          // 构造函数调用虚函数virtual void log() = 0;    // 纯虚函数
};class Derived : public Base {
public:void log() override { cout << "Derived Log" << endl; }
};
  • 执行流程:创建 Derived 对象 -> 调用 Base 构造函数 -> 尝试调用 log()。
  • 结果:由于此时 vptr 指向 Base 的表,而 Base::log 是空的(= 0),程序会抛出 pure virtual method called 运行时错误并直接崩溃(Crash)。

4. 更好的替代方案

如果你确实需要在初始化时根据子类类型执行不同的逻辑,该怎么办?

方案 A:通过参数传递(推荐)

将差异化的逻辑作为参数传递给基类构造函数,而不是依赖虚函数。

class Base {
public:Base(string type) { cout << "Initializing " << type << endl; }
};class Derived : public Base {
public:Derived() : Base("Derived") {} // 在初始化列表中明确告知基类
};

方案 B:工厂模式或二段式初始化

在对象完全构造完毕后,再调用一个初始化函数。

auto obj = new Derived();
obj->init(); // 此时对象已完全成型,多态正常工作

总结

阶段 对象的“身份” 虚函数调用结果
基类构造中 基类对象 调用基类版本(若为纯虚则崩溃)
派生类构造中 派生类对象 正常多态
析构过程中 随着层次逐层“退化” 调用当前层及以上的版本

记住一句话:在基类构造和析构期间,多态是“死”的。

相关新闻

  • 12月26日
  • Java毕设选题推荐:基于java的校园闲置物品交易平台设计与实现基于java的大学生闲置物品交易平台设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 05. 图像的运算

最新新闻

  • 2026年香薰棒深度测评:如何为品牌生产匹配最佳供应方案? - 热点速览
  • 2026年6月回转风机厂家推荐指南 - 多才菠萝
  • 免费搭建微信公众号RSS订阅:终极私有化部署完整指南
  • 2026年青岛留学中介综合测评,个性化方案与模板化服务区别 - 资讯速览
  • Cherry Markdown:企业级文档自动化工作流的技术架构与实践
  • 地址智能识别Pro实战指南:5步实现精准地址解析

日新闻

  • 2026年不锈钢卷板厂家推荐排行榜:冷轧热轧/304/201不锈钢卷板,高颜值耐腐蚀源头厂家实力精选 - 企业推荐官【官方】
  • FLUX.1-dev FP8模型实战指南:24GB以下显卡高效部署方案
  • 2026佛山长途搬家价目表:跨省跨市搬家费用完整计算指南 - 从来都是英雄出少年

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号