Chris_M_Thomasson

Dynamic Extending vtable attempt...

Jul 25th, 2017
195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.85 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5.  
  6. /* Object Interface
  7. __________________________________________________*/
  8. typedef void(*ct_iobject_fp_destroy) (void*);
  9. typedef void(*ct_iobject_fp_print) (void*, FILE*);
  10.  
  11. struct ct_iobject_vtable
  12. {
  13. ct_iobject_fp_destroy fp_destroy;
  14. ct_iobject_fp_print fp_print;
  15. };
  16.  
  17. #define ct_iobject_vtable(mp_self) \
  18. ((((struct ct_iobject_vtable*)(*((void**)(mp_self)))))
  19.  
  20. #define ct_iobject_print(mp_self, mp_file) \
  21. (ct_iobject_vtable(mp_self)->fp_print((mp_self), (mp_file))))
  22.  
  23. #define ct_iobject_destroy(mp_self) \
  24. (ct_iobject_vtable(mp_self)->fp_destroy((mp_self))))
  25.  
  26.  
  27. /* Person Interface
  28. __________________________________________________*/
  29. typedef void(*ct_person_fp_talk) (void*, char const*, FILE*);
  30.  
  31. struct ct_person_vtable
  32. {
  33. struct ct_iobject_vtable m_object;
  34. };
  35.  
  36. struct ct_person_prv_vtable
  37. {
  38. ct_person_fp_talk fp_talk;
  39. };
  40.  
  41. #define ct_iperson_talk(mp_self, mp_msg, mp_file) \
  42. ((mp_self)->m_prv_vtable.fp_talk((mp_self), (mp_msg), (mp_file)))
  43.  
  44. static void ct_person_print(void* raw_self, FILE* file);
  45. static void ct_person_talk(void* raw_self, char const* msg, FILE* file);
  46. static void ct_person_destroy(void* raw_self);
  47.  
  48. static struct ct_person_vtable const g_ct_person_vtable = {
  49. {
  50. ct_person_destroy,
  51. ct_person_print
  52. }
  53. };
  54.  
  55.  
  56. /* Person Impl
  57. __________________________________________________*/
  58. struct ct_person
  59. {
  60. struct ct_person_vtable const* m_vtable;
  61. struct ct_person_prv_vtable m_prv_vtable;
  62. char* name;
  63. };
  64.  
  65. static int
  66. ct_person_create(
  67. struct ct_person* const self,
  68. char const* name
  69. ) {
  70. size_t name_size = strlen(name) + 1;
  71.  
  72. self->name = calloc(1, name_size);
  73.  
  74. if (self->name)
  75. {
  76. strcpy(self->name, name);
  77.  
  78. // setup vtable
  79. self->m_vtable = &g_ct_person_vtable;
  80. self->m_prv_vtable.fp_talk = ct_person_talk;
  81.  
  82. printf("(%p:ct_person_create):(name:%s)\n",
  83. (void*)self, self->name);
  84.  
  85. return 0;
  86. }
  87.  
  88. return -1;
  89. }
  90.  
  91. static void
  92. ct_person_print(
  93. void* raw_self,
  94. FILE* file
  95. ) {
  96. struct ct_person* const self = raw_self;
  97.  
  98. fprintf(file, "(%p:ct_person_print):(name:%s)\n",
  99. (void*)self, self->name);
  100. }
  101.  
  102. static void
  103. ct_person_talk(
  104. void* raw_self,
  105. char const* msg,
  106. FILE* file
  107. ) {
  108. struct ct_person* const self = raw_self;
  109.  
  110. fprintf(file, "(%p:ct_person_talk):(name:%s says %s)\n",
  111. (void*)self, self->name, msg);
  112. }
  113.  
  114. static void
  115. ct_person_destroy(
  116. void* raw_self
  117. ) {
  118. struct ct_person* const self = raw_self;
  119.  
  120. printf("(%p:ct_person_destroy):(name:%s)\n",
  121. (void*)self, self->name);
  122.  
  123. free(self->name);
  124. }
  125.  
  126.  
  127.  
  128. /* Employee Interface
  129. __________________________________________________*/
  130. static void ct_employee_print(void* raw_self, FILE* file);
  131. static void ct_employee_destroy(void* raw_self);
  132.  
  133. static struct ct_person_vtable const g_ct_employee_vtable = {
  134. {
  135. ct_employee_destroy,
  136. ct_employee_print
  137. }
  138. };
  139.  
  140.  
  141. /* Employee Impl
  142. __________________________________________________*/
  143. struct ct_employee
  144. {
  145. struct ct_person m_person;
  146. int id;
  147. };
  148.  
  149. static int
  150. ct_employee_create(
  151. struct ct_employee* const self,
  152. char const* name,
  153. int id
  154. ) {
  155. int status = ct_person_create(&self->m_person, name);
  156.  
  157. if (!status)
  158. {
  159. // setup vtable
  160. self->m_person.m_vtable = &g_ct_employee_vtable;
  161.  
  162. self->id = id;
  163.  
  164. return 0;
  165. }
  166.  
  167. return status;
  168. }
  169.  
  170. static void
  171. ct_employee_print(
  172. void* raw_self,
  173. FILE* file
  174. ) {
  175. struct ct_employee* const self = raw_self;
  176.  
  177. fprintf(file, "(%p:ct_employee_print):(id:%d)\n",
  178. (void*)self, self->id);
  179.  
  180. // explicit chain
  181. ct_person_print(&self->m_person, file);
  182. }
  183.  
  184. static void
  185. ct_employee_destroy(
  186. void* raw_self
  187. ) {
  188. struct ct_employee* const self = raw_self;
  189.  
  190. printf("(%p:ct_employee_destroy):(id:%d)\n",
  191. (void*)self, self->id);
  192.  
  193. // explicit chain
  194. ct_person_destroy(&self->m_person);
  195. }
  196.  
  197.  
  198. /* Testing 123...
  199. __________________________________________________*/
  200. int main(void)
  201. {
  202. struct ct_employee employee;
  203.  
  204. if (!ct_employee_create(&employee, "Chris M. Thomasson", 103))
  205. {
  206. struct ct_person* const person = &employee.m_person;
  207.  
  208. ct_iperson_talk(person, "Hello World!", stdout);
  209. ct_iobject_print(&employee, stdout);
  210. ct_iobject_destroy(person);
  211. }
  212.  
  213. printf("\n_______________________________________\n");
  214.  
  215. if (!ct_employee_create(&employee, "Jane Doe", 1203))
  216. {
  217. struct ct_person* const person = &employee.m_person;
  218.  
  219. ct_iobject_print(person, stdout);
  220. ct_iperson_talk(person, "Goodbye", stdout);
  221. ct_iobject_destroy(&employee);
  222. }
  223.  
  224. return 0;
  225. }
Advertisement
Add Comment
Please, Sign In to add comment