#include #include #include "flash_light.h" typedef struct pkt_cell *pkt_cell_t; // 电池接口 struct pkt_cell { void (*init)(void *t); void (*set_link_to_next)(void *t, pkt_cell_t cell); int (*get_power)(void *t); }; typedef struct pkt_light *pkt_light_t; // 手电筒接口 struct pkt_light { void (*init)(void *t); void (*add_cell)(void *t, void *cell); int (*power)(void *t); }; typedef struct pkt_panasonic_cell *pkt_panasonic_cell_t; // 松下电池类 struct pkt_panasonic_cell { struct pkt_cell cell; int pwr; const char *name; pkt_cell_t next; }; typedef struct pkt_cat_cell *pkt_cat_cell_t; // 黑猫电池类 struct pkt_cat_cell { struct pkt_cell cell; int pwr; const char *name; pkt_cell_t next; }; typedef struct pkt_falsh_light *pkt_falsh_light_t; // 手电筒类 struct pkt_falsh_light { struct pkt_light light; pkt_cell_t head; /* 用于存储多态对象的链表头 */ pkt_cell_t tail; /* 用于存储多态对象的链表尾 */ }; // 松下电池接口实现 void pkt_panasonic_cell_init(void *t) { pkt_panasonic_cell_t this = (pkt_panasonic_cell_t)t; this->name = "panasonic"; this->pwr = 20; this->next = NULL; } void pkt_panasonic_cell_set_link_to_next(void *t, pkt_cell_t cell) { pkt_panasonic_cell_t this = (pkt_panasonic_cell_t)t; this->next = cell; } int pkt_panasonic_cell_get_power(void *t) { pkt_panasonic_cell_t this = (pkt_panasonic_cell_t)t; pkt_cell_t pc = this->next; if (NULL == pc) { return this->pwr; } else { pc = this->next; return (this->pwr + pc->get_power(pc)); } } pkt_panasonic_cell_t pkt_structure_panasonic_cell(void) { pkt_panasonic_cell_t n = (pkt_panasonic_cell_t)malloc(sizeof(struct pkt_panasonic_cell)); if (NULL == n) return NULL; n->cell.init = pkt_panasonic_cell_init; n->cell.set_link_to_next = pkt_panasonic_cell_set_link_to_next; n->cell.get_power = pkt_panasonic_cell_get_power; return n; } // 黑猫电池接口实现 void pkt_cat_cell_init(void *t) { pkt_cat_cell_t this = (pkt_cat_cell_t)t; this->name = "cat"; this->pwr = 15; this->next = NULL; } void pkt_cat_cell_set_link_to_next(void *t, pkt_cell_t cell) { pkt_cat_cell_t this = (pkt_cat_cell_t)t; this->next = cell; } int pkt_cat_cell_get_power(void *t) { pkt_cat_cell_t this = (pkt_cat_cell_t)t; pkt_cell_t pc = this->next; if (NULL == pc) { return this->pwr; } else { pc = this->next; return (this->pwr + pc->get_power(pc)); // 递归 } } pkt_cat_cell_t pkt_structure_cat_cell(void) { pkt_cat_cell_t n = (pkt_cat_cell_t)malloc(sizeof(struct pkt_cat_cell)); if (NULL == n) return NULL; n->cell.init = pkt_cat_cell_init; n->cell.set_link_to_next = pkt_cat_cell_set_link_to_next; n->cell.get_power = pkt_cat_cell_get_power; return n; } // 手电筒接口实现 void pkt_light_init(void *t) { pkt_falsh_light_t this = (pkt_falsh_light_t)t; this->head = this->tail = NULL; } void pkt_light_add_cell(void *t, void *cell) { pkt_falsh_light_t this = (pkt_falsh_light_t)t; pkt_cell_t tcell = (pkt_cell_t)cell; pkt_cell_t pc; if(this->head == NULL) // 第一个节点 { this->head = tcell; this->tail = this->head; } else { pc = this->tail; pc->set_link_to_next(pc, tcell); this->tail = tcell; } } int pkt_light_power(void *t) { pkt_falsh_light_t this = (pkt_falsh_light_t)t; pkt_cell_t pc = this->head; return pc->get_power(pc); } pkt_falsh_light_t pkt_structure_falsh_light_cell(void) { pkt_falsh_light_t n = (pkt_falsh_light_t)malloc(sizeof(struct pkt_falsh_light)); if (NULL == n) return NULL; n->light.init = pkt_light_init; n->light.add_cell = pkt_light_add_cell; n->light.power = pkt_light_power; return n; } int main(void) { // 构造对象 pkt_falsh_light_t falsh_light = pkt_structure_falsh_light_cell(); pkt_panasonic_cell_t panasonic_cell = pkt_structure_panasonic_cell(); pkt_cat_cell_t cat_cell = pkt_structure_cat_cell(); pkt_cat_cell_t cat_cell1 = pkt_structure_cat_cell(); // 初始化对象 falsh_light->light.init(falsh_light); panasonic_cell->cell.init(panasonic_cell); cat_cell->cell.init(cat_cell); cat_cell->cell.init(cat_cell1); // 将电池串联到手电筒里面 falsh_light->light.add_cell(falsh_light, panasonic_cell); /* 串联一节松下电池到手电筒 */ falsh_light->light.add_cell(falsh_light, cat_cell); /* 串联一节黑猫电池到手电筒 */ falsh_light->light.add_cell(falsh_light, cat_cell1); /* 串联一节黑猫电池到手电筒 */ // 打印手电筒的电量 printf("falsh light power = %d\n", falsh_light->light.power(falsh_light)); return 0; }