QEMU源码全解析 —— 块设备虚拟化(4)

接前一篇文章: QEMU源码全解析 —— 块设备虚拟化(3)

本文内容参考:

《趣谈 Linux操作系统 》 —— 刘超, 极客时间

QEMU /KVM源码解析与应用》 —— 李强,机械工业出版社

类模板是创建类的模式_创建类是的模版-CSDN博客

【C/C++】 类模板与模板类详解|函数指针\指针函数|函数模板和类模板|普通参数模板、类参数模板-CSDN博客

特此致谢!

QEMU初始化阶段的块设备虚拟化

从模板生成类和类的实例化

上一回以virtio block device为例,讲解了QEMU中类的继承。

每一层都有一个type_init函数,type_init函数用于注册类。同时,每一层也有一个class_init,用于从TypeImpl生产xxxClass。

这是很明显的面向对象(如C++和Java)思想在C语言中的移植和体现。笔者并非C++工程师,对Java也玩得不熟,因此这里有必要进行知识补强。QEMU中有大量的相似代码,不把这一块弄清楚,就无法真正和彻底地掌握QEMU的精髓。

从TypeImpl生成xxxClass

类模板使用关键字template引入一个类模板。类模板是创建类的模式,通过提供模板参数来实现,,例如Point<int>。

每当使用不同的模板参数时,编译器就会生成一个新的类实例,具有新的成员函数。
也就是说,Point<int>::moveTo是一个函数,Point<double>::moveTo是另一个函数,这正是手动编写这些函数会发生的情况。如果两个不同的源文件都使用Point<int>,编译器和链接器会确保它们共享同一个模板实例。

类模板是一个蓝图,它不是具体的类,而是用来创建类的一种模型或框架。类模板允许定义函数和成员变量的数据类型作为模板参数typename T或class T,这样就可以根据需要使用不同的数据类型来创建类。

说白了,类模板就是用T作为类里面变量和成员函数参数的数据类型的占位符。模板类就是把占位符替换成实际数据类型(int、float等)后的类。

说明:

template<typename T> 与 template<class T>等价

在C++的Template中很多地方都用到了typename与class这两个关键字,有时候这两者可以替换,那么这两个关键字是否完全一样呢?

事实上class用于定义类,在模板引入c++后,最初定义模板的方法为:template<class T>。这里class关键字表明T是一个类型,后来为了避免class在这两个地方的使用可能给人带来混淆,所以引入了typename这个关键字,它的作用同class一样表明后面的符号为一个类型,这样在定义模板的时候可以使用下面的方式了:

template<typename T>

在模板定义语法中关键字class与typename的作用完全一样。

类实例化

每一层还可能有instance_init(也可能没有),用于将xxxClass初始化为实例。TYPE_DEVICE的instance_init为device_initfn;TYPE_VIRTIO_BLK的instance_init为virtio_blk_instance_init。

在面向对象的编程中,通常把用类创建对象的过程称为实例化。如Date date = new Date();就是用日期类创建了一个日期的对象,就叫对象的实例化。

多数语言中,实例化一个对象就是为对象开辟内存空间,或者是不用声明,直接使用new构造函数名,建立一个临时对象。

对于QEMU的类继承机制,更加贴近的是Java反射机制。对于Java反射机制的详细介绍以及QEMU类继承与其的对应关系,在下一回中进行详细讲解。