Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- /* Object Interface
- __________________________________________________*/
- typedef void(*ct_iobject_fp_destroy) (void*);
- typedef void(*ct_iobject_fp_print) (void*, FILE*);
- struct ct_iobject_vtable
- {
- ct_iobject_fp_destroy fp_destroy;
- ct_iobject_fp_print fp_print;
- };
- #define ct_iobject_vtable(mp_self) \
- ((((struct ct_iobject_vtable*)(*((void**)(mp_self)))))
- #define ct_iobject_print(mp_self, mp_file) \
- (ct_iobject_vtable(mp_self)->fp_print((mp_self), (mp_file))))
- #define ct_iobject_destroy(mp_self) \
- (ct_iobject_vtable(mp_self)->fp_destroy((mp_self))))
- /* Person Interface
- __________________________________________________*/
- typedef void(*ct_person_fp_talk) (void*, char const*, FILE*);
- struct ct_person_vtable
- {
- struct ct_iobject_vtable m_object;
- };
- struct ct_person_prv_vtable
- {
- ct_person_fp_talk fp_talk;
- };
- #define ct_iperson_talk(mp_self, mp_msg, mp_file) \
- ((mp_self)->m_prv_vtable.fp_talk((mp_self), (mp_msg), (mp_file)))
- static void ct_person_print(void* raw_self, FILE* file);
- static void ct_person_talk(void* raw_self, char const* msg, FILE* file);
- static void ct_person_destroy(void* raw_self);
- static struct ct_person_vtable const g_ct_person_vtable = {
- {
- ct_person_destroy,
- ct_person_print
- }
- };
- /* Person Impl
- __________________________________________________*/
- struct ct_person
- {
- struct ct_person_vtable const* m_vtable;
- struct ct_person_prv_vtable m_prv_vtable;
- char* name;
- };
- static int
- ct_person_create(
- struct ct_person* const self,
- char const* name
- ) {
- size_t name_size = strlen(name) + 1;
- self->name = calloc(1, name_size);
- if (self->name)
- {
- strcpy(self->name, name);
- // setup vtable
- self->m_vtable = &g_ct_person_vtable;
- self->m_prv_vtable.fp_talk = ct_person_talk;
- printf("(%p:ct_person_create):(name:%s)\n",
- (void*)self, self->name);
- return 0;
- }
- return -1;
- }
- static void
- ct_person_print(
- void* raw_self,
- FILE* file
- ) {
- struct ct_person* const self = raw_self;
- fprintf(file, "(%p:ct_person_print):(name:%s)\n",
- (void*)self, self->name);
- }
- static void
- ct_person_talk(
- void* raw_self,
- char const* msg,
- FILE* file
- ) {
- struct ct_person* const self = raw_self;
- fprintf(file, "(%p:ct_person_talk):(name:%s says %s)\n",
- (void*)self, self->name, msg);
- }
- static void
- ct_person_destroy(
- void* raw_self
- ) {
- struct ct_person* const self = raw_self;
- printf("(%p:ct_person_destroy):(name:%s)\n",
- (void*)self, self->name);
- free(self->name);
- }
- /* Employee Interface
- __________________________________________________*/
- static void ct_employee_print(void* raw_self, FILE* file);
- static void ct_employee_destroy(void* raw_self);
- static struct ct_person_vtable const g_ct_employee_vtable = {
- {
- ct_employee_destroy,
- ct_employee_print
- }
- };
- /* Employee Impl
- __________________________________________________*/
- struct ct_employee
- {
- struct ct_person m_person;
- int id;
- };
- static int
- ct_employee_create(
- struct ct_employee* const self,
- char const* name,
- int id
- ) {
- int status = ct_person_create(&self->m_person, name);
- if (!status)
- {
- // setup vtable
- self->m_person.m_vtable = &g_ct_employee_vtable;
- self->id = id;
- return 0;
- }
- return status;
- }
- static void
- ct_employee_print(
- void* raw_self,
- FILE* file
- ) {
- struct ct_employee* const self = raw_self;
- fprintf(file, "(%p:ct_employee_print):(id:%d)\n",
- (void*)self, self->id);
- // explicit chain
- ct_person_print(&self->m_person, file);
- }
- static void
- ct_employee_destroy(
- void* raw_self
- ) {
- struct ct_employee* const self = raw_self;
- printf("(%p:ct_employee_destroy):(id:%d)\n",
- (void*)self, self->id);
- // explicit chain
- ct_person_destroy(&self->m_person);
- }
- /* Testing 123...
- __________________________________________________*/
- int main(void)
- {
- struct ct_employee employee;
- if (!ct_employee_create(&employee, "Chris M. Thomasson", 103))
- {
- struct ct_person* const person = &employee.m_person;
- ct_iperson_talk(person, "Hello World!", stdout);
- ct_iobject_print(&employee, stdout);
- ct_iobject_destroy(person);
- }
- printf("\n_______________________________________\n");
- if (!ct_employee_create(&employee, "Jane Doe", 1203))
- {
- struct ct_person* const person = &employee.m_person;
- ct_iobject_print(person, stdout);
- ct_iperson_talk(person, "Goodbye", stdout);
- ct_iobject_destroy(&employee);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment