首页 > 编程语言 >C++:虚函数和虚表详细总结

C++:虚函数和虚表详细总结

时间:2024-08-23 13:21:51浏览次数:8  
标签:虚表 函数 show C++ Base 基类 指针

一、虚函数 (Virtual Functions)

1. 定义

虚函数是基类中使用 virtual 关键字声明的成员函数,支持动态多态性。通过基类指针或引用调用虚函数时,会根据实际对象类型选择调用相应的函数实现。

2. 声明和定义

  • 虚函数的声明

    class Base 
    {
    public:
        virtual void show(); // 声明虚函数
    };
    
  • 在派生类中重写虚函数

    class Derived : public Base 
    {
    public:
        void show() override; // 使用 override 关键字可选
    };
    

3. 动态绑定

通过基类指针或引用调用虚函数时,C++ 编译器会进行动态绑定,决定在运行时调用哪个版本的函数。

Base* b = new Derived();
b->show(); // 输出:Derived class show() called.
//动态绑定

4. 纯虚函数

  • 定义:没有实现的虚函数,用于定义接口,使用 = 0 声明。
class AbstractBase 
{
public:
    virtual void show() = 0; // 纯虚函数
};

包含纯虚函数的类称为抽象类,无法实例化。

二、虚表 (Vtable)

1. 定义

虚表是由编译器为每个包含虚函数的类生成的结构,包含该类所有虚函数的指针。

2. 虚表的结构

  • 每个包含虚函数的类都有一个虚表,当调用的类为虚类时,会访问这个表,寻找具体实现。
  • 如果子类未重写某个虚函数,则虚表中会指向父类的实现。
  • 如果子类重写了某个虚函数,则虚表中会指向该类的实现.

3. 虚表的示例

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

class Derived : public Base {
    // No override
};

int main() {
    Base* b = new Derived();
    b->show(); // Calls Base::show()
    delete b;
    return 0;
}
4. 内存布局
  • Base 的虚表:
    [0] -> Base::show()
    
  • Derived 的虚表(未重写的情况下):
    [0] -> Base::show() // 指向父类的实现
    

5. 虚指针 (vptr)

  • 每个对象实例中都有一个虚指针,指向该对象所属类的虚表。
  • 虚指针通常是对象的第一个成员。

三、虚函数的特点

  1. 动态多态性:通过基类指针或引用调用子类的实现,支持在运行时决定函数调用。

  2. 基类指针和引用:允许使用基类类型来引用和操作派生类对象。

  3. 封装和保护:基类不需要了解具体的派生类实现,增强了代码的模块化和可维护性。

  4. 构造与析构的特殊性:构造时不调用派生类的虚函数,析构时确保派生类析构函数被调用。

  5. 性能开销

    • 空间开销:每个类需要存储虚表和每个对象需要一个虚指针。
    • 时间开销:调用虚函数时需要通过虚表查找函数地址,相比于普通函数调用有额外的开销。

四、虚函数的使用场景

  1. 实现接口:通过纯虚函数定义接口类。

  2. 多态行为:在需要不同对象间以相同方式处理时(如图形、游戏对象等)。

  3. 框架设计:在库或框架设计中,通过虚函数提供扩展点,让用户自定义行为。

标签:虚表,函数,show,C++,Base,基类,指针
From: https://blog.csdn.net/m0_73727069/article/details/141463489

相关文章

  • Clion配置-运行多个单独cpp代码的main函数
    修改CMakeLists.txt文件为project(YourProjectName)set(CMAKE_CXX_STANDARD11)#遍历项目二级目录下所有的.cpp文件file(GLOBfiles*/*.cpp)foreach(file${files})string(REGEXREPLACE".+/(.+)/(.+)\\..*""\\1-\\2"exe${file})add_exec......
  • c++ chrono头文件内Duration 、time_point和Clock
    前言        http://t.csdnimg.cn/eprLZ中介绍了关于chrono的基本操作,本文来介绍chrono与其他类的关系。内容Duration    duration表示一段时间间隔template<classRep,classPeriod=std::ratio<1>>classduration        Rep表示持续时......
  • 【Python】函数的定义和调用、形参和实参、函数的返回值、多元赋值、全局和局部变量
    文章目录函数的定义函数的调用形参和实参函数的返回值一个return多个return多元赋值变量作用域函数内的变量全局变量和局部变量修改全局变量函数的定义函数的定义:分配任务def函数名(形参列表): 函数体 return返回值def:define,定义形参列表中,可以有多个形......
  • C++基础 — 数组学习
    目录一、概述二、一维数组1.一维数组定义方式2.一维数组数组名二、二维数组1.二维数组定义方式2.二维数组数组名一、概述所谓数组,就是一个集合,里面存放了相同类型的数据元素。特点1:数组中的每个数据元素都是相同的数据类型;特点2:数组是由连续的内存位置组成的。二、......
  • C++入门基础知识29
    成长路上不孤单......
  • Terraform - 初解Terraform - 函数
    Functions函数https://developer.hashicorp.com/terraform/language/functionsTerraform语言包括许多内置函数,可以从表达式中调用这些函数来转换。函数调用的一般语法是函数名后跟括号中以逗号分隔的参数:function(arg1,arg2)数值函数-max()获取最大值-min()获取最小......
  • 关于在得帆云数据中台如何自定义函数
    UDF使用示例场景说明:使用udf编写一个函数Unit_Conversion(value)。在函数中根据value的值进行单位转化,并进行类型转化。1、导入依赖在pom.xml中将如下依赖进行导入。<dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec<......
  • C++(stoi())
    目录1.函数1.1参数1.2返回值1.3异常2.示例2.1使用base参数2.2pos参数的使用3.总结std::stoi()是C++11引入的一个标准库函数,用于将字符串转换为整数。与atoi()不同,stoi()提供了更强的功能,包括错误处理、支持指定进制等。1.函数intstoi(conststd::string&......
  • C++(atoi())
    目录1.函数1.1参数1.2返回值1.3注意事项2.示例3.atoi的局限性4.推荐替代函数atoi()是C++标准库中的一个函数,用于将C风格字符串转换为整数。atoi是"ASCIItoInteger"的缩写,它可以将包含数字的字符串解析为整数值。1.函数intatoi(constchar*str);1.1参......
  • C#使用委托实现函数回调,方法调用拦截
    C#使用委托实现函数回调,方法调用拦截回调方法、拦截方法定义publicclassAopHelper{publicstaticasyncTask<T>ExecuteGenericMethod<T>(Task<T>returnValue,Action<T>callBackAction,Action<Exception>exceptionAction,ActionfinallyAction){......