首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【C++】虚函数表(vtable),函数重载,函数签名,

【C++】虚函数表(vtable),函数重载,函数签名,

作者头像
用户11396661
发布2025-07-23 08:54:08
发布2025-07-23 08:54:08
13100
代码可运行
举报
文章被收录于专栏:C++开发C++开发
运行总次数:0
代码可运行

虚函数表存储的位置

是编译器分配一段只读数据区。

多态的底层实现逻辑

编译器找对应虚函数的步骤:

this指针->vptr指针->vtable表(虚函数表)->对应的虚函数(通过指针偏移,vptr就是虚函数表的起始指针,函数指针在虚函数表占的位置也是固定的)。

其实之前一直没明白为什么重定义不能实现多态?这两个例子就可以很好区分:

重定义:

代码语言:javascript
代码运行次数:0
运行
复制
#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
using namespace std;

class Animal {
public:
    void speak() {
        std::cout << "Animal speaks" << std::endl;
    }
};

class Dog : public Animal {
public:
    void speak(){
        std::cout << "Dog barks" << std::endl;
    }
};

class Cat : public Animal {
public:
    void speak() {
        std::cout << "Cat meows" << std::endl;
    }
};

int main() {
    Animal* a1 = new Dog();
    Animal* a2 = new Cat();

    a1->speak(); 
    a2->speak();  

    delete a1;
    delete a2;
}

在上面这个例子中,a1,a2都是Animal类型,他们在不同的作用域中,所以不会造成冲突。在调用speak函数的时候,直接去基类作用域Animal中寻找,都是找到的是基类的speak函数。(这和编译器寻找虚函数完全不同)

重写/覆盖

在Dog和Cat类中,都有一张虚函数表,他们继承父类Anima的虚函数表,因为在Cat和Dog中对soeak函数都进行了重写,所以他们自己的虚函数表的指针就发生了变化(在虚函数表中,对父类的speak函数进行覆盖)。这样在调用对应的虚函数的时候,就可以分别调用不同的虚函数了。调用的过程也是上面这样:his指针->vptr指针->vtable表(虚函数表)->对应的虚函数


为什么只有非静态成员函数才可以是虚拟的?

一个非静态成员函数函数在前面加上virtual就变成了虚函数。

因为虚函数是在虚函数表中的,虚函数表要靠vptr才能找到,vptr要这个对象的this指针才能找到。静态成员函数是不需要靠


虚函数的分类有:纯虚函数和普通虚函数。

有纯虚函数的类不能进行实例化,必须在子类重写以后才能实例化。

1.什么情况下会有虚函数表?

当一个类有虚函数的时候,就会有虚函数表。

2.实例化出来的对象是怎么去调用虚函数的?

对象会有一个指向虚函数表的虚指针vptr这个指针在64位平台是8字节,在32位平台是4字节),vptr是虚函数表的起始指针,通过指针的偏移就可以找到对应的虚函数地址,然后就可以进行函数调用。


函数重载,重定义,重写/覆盖:

函数重载(静态多态

在同一个作用域类,函数名相同,参数不同的函数构成函数重载。仅仅是返回值不同,不能构成函数重载。

问题:为什么编译器可以根据参数的不同,构造出不同的函数,从而形成函数重载,但是仅仅返回值不同,不能构成函数重载?

为了定位一个具体的函数,编程语言中引入了函数签名。

函数签名

1.函数名称。

2.参数列表:参数的个数,类型,顺序不同,都可以视作为参数列表的不同。

在C++语言中,函数签名没有包含返回值(但是有的编程语言中把返回值也作为函数签名的一部分),所以如果一个函数的名称相同,参数列表相同。只有返回值不同,他们的函数签名是一样的。编译器就不能区分他们了。

所以函数名相同,参数的顺序和个数和类型不同,可以区分出不同的函数,这些函数叫函数虫子啊。

重定义:

重定义在上面已经讲过了。

重写/覆盖

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-07-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 虚函数表存储的位置
  • 多态的底层实现逻辑
    • 重定义:
    • 重写/覆盖
  • 为什么只有非静态成员函数才可以是虚拟的?
  • 虚函数的分类有:纯虚函数和普通虚函数。
    • 1.什么情况下会有虚函数表?
    • 2.实例化出来的对象是怎么去调用虚函数的?
  • 函数重载,重定义,重写/覆盖:
    • 函数重载(静态多态)
      • 函数签名
    • 重定义:
    • 重写/覆盖
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档