服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++动态联编介绍

C++动态联编介绍

2022-08-09 10:30梁唐 C/C++

这篇文章主要介绍了C++动态联编,在C++中,联编是指一个计算机程序的不同部分彼此关联的过程。按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编和动态联编

文章转自:公众号:Coder梁(ID:Coder_LT)

一、静态联编和动态联编

当我们使用程序调用函数的时候,究竟应该执行哪一个代码块呢?将源代码中的函数调用解释为执行特定的函数代码块这个过程被称为函数名联编(binding)。

在C语言当中,这非常简单,因为每个函数名都对应一个不同的函数。而在C++当中,由于支持了函数重载,使得这个任务变得更加复杂。编译器必须要查看函数的参数以及函数名才能确定。好在函数的选择以及参数在编译的时候都是确定的,所以这部分联编在编译时就能完成,这种联编被称为静态联编。

在有了虚函数之后, 这个工作变得更加复杂。因为使用哪一个函数不能在编译时确定了,因为编译器不知道用户将选择哪个类型的对象。所以,编译器必须能在程序运行的时候选择正确的虚函数,这被称为动态联编。

1.指针和引用类型的兼容性

在C++当中,动态联编与指针和引用调用方法相关,这是由继承控制的。前文当中说过,公有继承建立的is-a关系,使得我们可以用父类指针或引用指向子类的对象。而在C++当中,是不允许将一种类型的地址赋值给另外一种类型的指针的。

下面两种操作都是非法的:

?
1
2
3
double x = 2.5;
int *pi = &x; // 非法
long &r = x; // 非法

将派生类引用或指针转换成基类的引用和指针称为向上强制转换(upcasting),这种规则是is-a关系的一部分。因为派生类继承了基类当中所有的数据成员和成员函数,因此基类成员能够进行的操作都适用于子类成员,所以向上强制转换是可传递的。

如果反过来呢?将父类对象传递给子类指针呢?这种操作被称为向下强制转换(downcasting),在不使用强制转换的前提下是不允许的。因为is-a关系通常是不可逆的,派生类当中往往新增了一些数据成员或方法,不能保证在父类对象上一样还能兼容。

2.虚函数的工作原理

我们在使用虚函数的时候其实可以不需要知道当中的实现原理,但是了解了工作原理能够帮助我们更好地理解理念。另外在C++相关的开发面试当中经常会问起类似的实现细节。

通常,编译器处理虚函数的方法是:给每一个对象添加一个隐藏成员,这个成员当中保存了一个指向函数地址数组的指针,这种数组称为虚函数表。

这个虚函数表中存储了当前这个类对象的声明的虚函数的地址,我们来看一个例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Human {
    private:
    ...
     char name[40];
    public:
     virtual void show_name();
     virtual void show_all();
     ...
};
 
class Hero : public Human{
    private:
     ...
        char power[20];
    public:
     void show_all();
        virtual void show_power();
     ...
};

对于Human类型的对象,它当中除了类中声明的内容之外,还会额外多一个指针,指向一个列表,比如是[1024,1222]。

这里的1024和1222分别是show_nameshow_all两个函数代码块的地址。

同样Hero子类当中也会有这样一个指针指向一个虚函数的列表,由于我们在Hero子类当中没有重载show_name方法,所以Hero类型的对象中的列表中的第一个元素仍然是1024。由于我们重载了show_all方法,以及我们新增了一个show_power的虚函数,因此它的虚函数列表可能是[1024,2333,3777]

简单来说,当我们调用虚函数的时候, 编译器会先通过每个对象中的虚函数列表指针拿到虚函数列表。然后在找到对应位置的虚函数代码块的地址,最后进行执行。

显然这个过程涉及到维护虚函数地址表,以及函数执行时有额外的查表操作,既带来了存储空间的消耗,也带来了性能的消耗。

到此这篇关于C++动态联编介绍的文章就介绍到这了,更多相关C++动态联编内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

延伸 · 阅读

精彩推荐
  • C/C++C++类的大小介绍

    C++类的大小介绍

    这篇文章主要介绍了C++类的大小,在C++中,结构体和类的唯一区别就是结构体和类具有不同的默认访问控制属性,下面一起进入文章查看详细内容...

    学渣的C/C++3442022-02-22
  • C/C++讲解C语言编程中指针赋值的入门实例

    讲解C语言编程中指针赋值的入门实例

    这篇文章主要介绍了讲解C语言编程中指针赋值的入门实例,通过const int i与int *const pi这样两个例子来分析指针的赋值和地址指向,需要的朋友可以参考下...

    C语言教程网11362021-03-17
  • C/C++C语言宏函数container of()简介

    C语言宏函数container of()简介

    这篇文章介绍了C语言宏函数container of(),对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...

    叨陪鲤7472022-07-19
  • C/C++一文学会数据结构-堆

    一文学会数据结构-堆

    本文主要介绍了数据结构-堆,文中通过图片和大量的代码讲解的非常详细,需要学习的朋友可以参考下这篇文章,希望可以帮助到你...

    双鱼21110962021-12-23
  • C/C++如何实现循环队列

    如何实现循环队列

    本文主要介绍了C语言循环队列的实现,对于数据结构与算法的研究有所帮助,需要的朋友可以参考下...

    zyuqiang8812021-03-03
  • C/C++C++ 操作系统内存分配算法的实现详解

    C++ 操作系统内存分配算法的实现详解

    本文主要介绍了在动态分区管理方式下采用不同的分配算法实现主存分配和实现主存回收,旨在帮助学生理解在动态分区管理方式下应怎样实现主存空间的...

    Carmelo_77852022-02-25
  • C/C++树存储结构的几种表示方法

    树存储结构的几种表示方法

    今天小编就为大家分享一篇关于树存储结构的几种表示方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来...

    BLSxiaopanlaile12042021-07-24
  • C/C++C++实现显示MP3文件信息的方法

    C++实现显示MP3文件信息的方法

    这篇文章主要介绍了C++实现显示MP3文件信息的方法,可实现显示如作者、专辑等(libZPlay)信息的功能,需要的朋友可以参考下...

    红薯10282021-02-27