<返回首页

探秘C++虚函数:解密多态的奥秘

2024-04-23 11:20:36    AI让生活更美好
加入收藏

虚函数—作为面向对象编程的核心特性之一,虚函数不仅在代码中发挥着重要作用,更是实现多态性的关键所在。

什么是虚函数?

在 C++ 中,虚函数是为了实现运行时多态性而设计的特殊类型的函数。通过在基类中声明虚函数,并在派生类中进行重写,可以在程序运行时根据实际对象类型确定调用的函数版本。这为我们提供了一种灵活的方式来处理继承关系,使得代码更具可扩展性和可维护性。

虚函数表的作用

虚函数表(virtual function table,简称 Vtable)是 实现虚函数的重要机制之一。每个类(包括含有虚函数的类)都会生成一个对应的虚函数表,其中存储了该类中所有虚函数的地址。

当对象被创建时,会分配一个指向其类的虚函数表的指针(虚指针)。通过这个指针,程序能够在运行时确定调用的函数版本,实现了动态绑定。注意与静态绑定混淆重载-静态绑定(链接)。

虚函数表的性质

派生类的虚函数表包含基类的虚函数表内容,并扩展新函数:派生类的虚函数表通常是在基类的虚函数表的基础上进行扩展的。 

示例代码解释 让我们通过一段简单的代码来说明虚函数表的工作原理:

#include <iostream>

class Base {
public:
    virtual void func1() {
        std::cout << "Base::func1()" << std::endl;
    }
    virtual void func2() {
        std::cout << "Base::func2()" << std::endl;
    }
};

class Derived : public Base {
public:
    void func1() override {
        std::cout << "Derived::func1()" << std::endl;
    }
    void func3() {
        std::cout << "Derived::func3()" << std::endl;
    }
};

int main() {
    Base* ptr = new Derived();
    ptr->func1(); // 动态绑定
    ptr->func2(); // 动态绑定
    delete ptr;
    return 0;
}

在这个示例中,我们创建了一个基类 Base 和一个派生类 Derived,后者重写了基类中的 func1()。

在 main() 函数中,我们创建了一个基类指针指向派生类对象,并通过该指针调用了两个虚函数 func1() 和 func2()。由于 func1() 是虚函数,并且对象是 Derived 类型,所以会动态绑定到 Derived::func1()。而 func2() 在派生类中没有被重写,所以会绑定到基类的版本。

虚函数表的大小

先看一个例子(操作环境64位系统)

//先看空类大小
class test {

};
//只有一个虚函数的类大小
class test1 
{
  public:
    virtual void function()
{
    std::cout << "function()" << std::endl;
    }
};
//两个虚函数类的大小
class test2 
{
  public:
    virtual void function1()
{
    std::cout << "function1()" << std::endl;
    }
    
    virtual void function2()
{
    std::cout << "function2()" << std::endl;
    }
};

int main()
{
  std::cout<<"sizeof test: "<<sizeof(test)<<std::endl;
  std::cout<<"sizeof test1: "<<sizeof(test1)<<std::endl;
  std::cout<<"sizeof test2: "<<sizeof(test2)<<std::endl;
  return 0;
}

类在内存中记录虚函数是以一个指针记录的,并且该指针指向一个数组,数组中装着的是虚函数的地址。同时,经过实验,64bit的编译器下,虚函数表的指针大小是8字节。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
推荐信息
 
抖音如何撰写吸睛标题
 
Python图像处理库OpenCV入门教程:实践与构建
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器...
 
微服务架构最佳实践-方法篇
 
揭秘 Python 江湖中的15个冷门但超能模块
 
数据库为啥要融合+AI化?甲骨文Oracle 23ai给出了回答
 
一招教你解决页面中关联id的转换
在工作中,我们经常有这样的业务情况,实体间通过id实现数据业务上的关联,比如订...
 
SQL实用技巧-行列转换
 
Spring注入还可以这样玩!涨知识了
假设你有两个 CommonDAO bean,每个都需要在不同的环境中使用。这时,你可以使...
 
GPT-4o:实现跨越文本与视觉的智能交互
 
北京被曝小升初“掐尖招生”,北京教委:两校违反阳光招生要求被约谈,责成
 
DIY从入门到放弃:CPU主频/倍频/睿频/超频别迷糊
不管手机还是电脑,我们都知道CPU性能的重要性,作为核心组件,CPU决定了整机的性...
 
《DNF》手游将于5月21日正式上线 迪丽热巴代言
 
腾讯市值已达阿里两倍多!原因何在
 
苹果回应更新iOS 17.5恢复已删除多年照片:不用担心自己隐私安全
 
仅7地住房限购 北上广深会全面取消吗?
每经记者 甄素静 每经编辑 陈梦妤 据诸葛数据研究中心不完全统计,截至目前,全...
 
“国家队”出手收储房产,楼市格局真的要变了?
 
30年期超长期特别国债,今天正式首发,个人投资者能买吗?一文看懂
 
OpenAI与Reddit建立合作伙伴关系,利用其内容训练人工智能
 
Q1营收增速放缓,百度苦寻新引擎
 
不再区分一本、二本 江西2024年将首次迎来新高考
新京报讯 根据教育部统一部署,江西省作为全国第四批启动高考综合改革的7省(区...
返回栏目