# 面向对象的设备模型

书接上回，说到device设备在设置了realized属性后会调用DeviceClass的realize函数进行初始化。那这个函数究竟是什么的？

要说清楚这件事，还得找一个具体的设备来说才能够看得清。

## qemu中的函数重载

DeviceClass类型中的realize成员在device\_class\_init()初始化函数中并没有被设置。这个函数的具体对应是在DeviceClass的子类型的类型初始化函数中设置的。

比如PCIDeviceClass就是DeviceClass的一个子类型。在它的类型初始化函数pci\_device\_class\_init中可以看到下面这段代码：

```
  k->realize = pci_qdev_realize;
```

所以在qemu的设备模型中其实采用了面向对象的编程方法。

## 面向对象的设备模型

讲了这么多，恐怕大家也听晕了。正所谓耳听为虚，眼见为实。我们来画一个图，看看e1000这个设备面向对象模型的样子。

```
       +--------------------------+                           +----------------------+
       |                          |                           |                      |
       |   ObjectClass            | <-------------------------|    Object            |
       |     class_init           |                           |    instance_init     |
       |                          |                           |(object_instance_init)|
       +--------------------------+                           +----------------------+
                 |                                                      |
                 |                                                      |
                 |                                                      |
                 v                                                      v
       +--------------------------+                           +----------------------+
       |                          |                           |                      |
       |   DeviceClass            |  <---------------------   |   DeviceState        |
       |     class_init           |                           |      instance_init   |
       |     (device_class_init)  |                           |      (device_initfn) |
       |                          |                           |                      |
       |     realize              |  overwrite by child class |                      |
       |     unrealize            |                           |                      |
       +--------------------------+                           +----------------------+
                 |                                                      |
                 |                                                      |
                 |                                                      |
                 v                                                      v
       +--------------------------+                           +----------------------+
       |                          |                           |                      |
       |   PCIDeviceClass         |  <---------------------   |   PCIDevice          |
       |     class_init           |                           |      instance_init   |
       |   (pci_device_class_init)|                           |      (NULL)          |
       |     realize              |                           |                      |
       |     (pci_qdev_realize)   |  call PCIDevice->realize  |                      |
       |     unrealize            |                           |                      |
       |     (pci_qdev_unrealize) |                           |                      |
       +--------------------------+                           +----------------------+
                 |                                                      |
                 |                                                      |
                 |                                                      |
                 v                                                      v
       +--------------------------+                           +----------------------+
       |                          |                           |                      |
       |   E1000BaseClass         |  <--------------------    |   E1000State         |
       |     class_init           |                           |      instance_init   |
       |     (e1000_class_init)   |                           | (e1000_instance_init)|
       |     realize              |                           |                      |
       |     (pci_e1000_realize)  |                           |                      |
       |     unrealize            |                           |                      |
       |                          |                           |                      |
       +--------------------------+                           +----------------------+
```

在这张图中体现了这么几点：

* 某个类型可以是另一个类型的子类型
* 某个设备实例包含了父类型的实例
* 实例和类型之间一一对应
* 类型的成员可以被子类重写

到这里，感觉终于可以说对qemu的设备模型有了那么一点点的了解。
