0

0

C++中的静态绑定和动态绑定有什么区别?(编译期确定与运行期虚函数寻址)

穿越時空

穿越時空

发布时间:2026-01-09 13:15:08

|

690人浏览过

|

来源于php中文网

原创

静态绑定在编译期确定函数调用目标,依据声明类型、函数签名和作用域,适用于非虚函数、重载、模板、static成员、全局函数及构造函数等场景。

c++中的静态绑定和动态绑定有什么区别?(编译期确定与运行期虚函数寻址)

静态绑定发生在编译期,靠函数签名和作用域决定调用哪个函数

静态绑定(也叫早期绑定)指的是编译器在编译阶段就确定了函数调用的目标地址。它不依赖对象的实际类型,只看指针/引用的**声明类型**,以及重载解析、模板实例化、作用域查找等规则。

常见触发场景包括:普通非虚函数调用、函数重载、模板函数、static 成员函数、全局函数、构造函数(除虚基类初始化外)。

  • 即使通过基类指针指向派生类对象,调用非虚函数时仍绑定到基类版本
  • 重载函数的选择完全基于参数类型(编译期可推导),与运行时对象内容无关
  • 内联函数、constexpr 函数必定静态绑定
class Base {
public:
    void func() { std::cout << "Base::func\n"; }
    virtual void vfunc() { std::cout << "Base::vfunc\n"; }
};
class Derived : public Base {
public:
    void func() { std::cout << "Derived::func\n"; } // 隐藏,非重写
    void vfunc() override { std::cout << "Derived::vfunc\n"; }
};

Base* ptr = new Derived(); ptr->func(); // 静态绑定 → 调用 Base::func(不是 Derived::func) ptr->vfunc(); // 动态绑定 → 调用 Derived::vfunc

动态绑定依赖虚函数表,运行时根据对象实际类型查表跳转

动态绑定(晚期绑定)只对声明为 virtual 的成员函数生效,且必须通过指针或引用调用(不能是直接对象调用)。它在运行期通过对象的虚函数表(vtable)和虚表指针(vptr)完成函数地址解析。

关键前提有三个:virtual 关键字 + 指针/引用调用 + 对象内存中含有效 vptr(即完整对象已构造完毕)。

立即学习C++免费学习笔记(深入)”;

DeepL
DeepL

DeepL是一款强大的在线AI翻译工具,可以翻译31种不同语言的文本,并可以处理PDF、Word、PowerPoint等文档文件

下载
  • 构造函数和析构函数中调用虚函数,行为是静态绑定(此时 vptr 尚未设置或已被销毁)
  • 纯虚函数在抽象基类中只占 vtable 槽位,具体实现由派生类填充
  • 多重继承下,vtable 可能不止一个(如虚继承会引入额外指针开销)
Base* ptr = new Derived();
ptr->vfunc(); // 运行时:读取 ptr 所指对象的 vptr → 查 vtable[1] → 跳转到 Derived::vfunc

虚函数调用性能开销主要来自间接跳转和缓存不友好

动态绑定不是“慢”,而是比静态绑定多出两次内存访问:一次读 vptr,一次查 vtable。现代 CPU 的分支预测和缓存能缓解大部分影响,但仍有真实代价:

  • 无法内联 —— 编译器不知道目标函数地址,失去优化机会
  • vtable 查找可能引发 cache miss,尤其在热路径频繁切换不同派生类对象时
  • 虚函数禁止 RVO 和某些 copy elision,影响对象构造效率
  • 使用 final 修饰虚函数或类,可让编译器重新启用静态绑定(GCC/Clang 支持)

容易误判“看似动态实为静态”的几种情况

很多初学者以为只要用了指针就是动态绑定,其实不然。以下写法全部是静态绑定:

  • Base b; b.vfunc(); —— 直接对象调用,无 vptr 参与,哪怕函数是 virtual
  • Derived d; Base& ref = d; ref.func(); —— func() 非虚,绑定到 Base::func
  • ptr->Base::vfunc(); —— 显式限定作用域,强制静态绑定
  • 构造函数体内调用 virtual 函数 —— 此时派生类部分尚未构造,vptr 指向当前类 vtable

真正需要动态行为时,务必确认三点:函数带 virtual、调用表达式左侧是基类指针或引用、右侧对象是完整构造后的派生类实例。

相关专题

更多
Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

61

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

31

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

72

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

20

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

21

2026.01.13

PHP缓存策略教程大全
PHP缓存策略教程大全

本专题整合了PHP缓存相关教程,阅读专题下面的文章了解更多详细内容。

7

2026.01.13

jQuery 正则表达式相关教程
jQuery 正则表达式相关教程

本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。

4

2026.01.13

交互式图表和动态图表教程汇总
交互式图表和动态图表教程汇总

本专题整合了交互式图表和动态图表的相关内容,阅读专题下面的文章了解更多详细内容。

49

2026.01.13

nginx配置文件详细教程
nginx配置文件详细教程

本专题整合了nginx配置文件相关教程详细汇总,阅读专题下面的文章了解更多详细内容。

11

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 6.7万人学习

C 教程
C 教程

共75课时 | 4万人学习

C++教程
C++教程

共115课时 | 12.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号