在过去的几个月里,我一直在尝试使用纯C进行编码,并尽可能地避免使用C ++(出于个人原因,C ++是一种很好的语言),但偶尔会出现这样的情况:当我用C ++编写代码时,我会错过一些我过去经常使用的概念,C语言中没有明显的等价物,其中一个概念是“接口”。经过几个小时的研究后,我想出了这个解决方案,但我担心我的代码将来可能会出错。以下是我想要做的示例代码:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef int (*on_affected_cb) (const char *msg);
typedef struct affectee_t affectee_t;
typedef struct type_a_t type_a_t;
typedef struct type_b_t type_b_t;
typedef struct type_c_t type_c_t;
typedef struct owner_t owner_t;
//******************************************************************************
struct affectee_t{ //interface
on_affected_cb on_affected;
};
void affectee_notify(affectee_t* self, const char* msg){
self->on_affected(msg);
}
//******************************************************************************
struct type_a_t{ //implementor a
affectee_t affectee;
int num;
};
static int type_a_on_affected (const char *msg){
printf("this is type a reading msg: %s\n", msg);
return 1000;
}
void type_a_init(type_a_t* self){
self->num = 0;
self->affectee.on_affected = type_a_on_affected;
}
//******************************************************************************
struct type_b_t{ //implementor b
affectee_t affectee;
char name[128];
};
static int type_b_on_affected (const char *msg){
printf("this is type b reading msg: %s\n", msg);
return 2000;
}
void type_b_init(type_b_t* self){
memset(self->name, 0, sizeof(self->name));
self->affectee.on_affected = type_b_on_affected;
}
//******************************************************************************
struct owner_t{ // ordinary struct/class
type_a_t ta;
type_b_t tb;
};
void owner_init(owner_t* self){
type_a_init(&self->ta);
type_b_init(&self->tb);
}
void owner_notify(owner_t* self){
const char msg[] = "what the f...!";
affectee_notify((affectee_t*)&self->ta, msg); //<- pointer casting!!!
affectee_notify((affectee_t*)&self->tb, msg); //<- same here
}
//******************************************************************************
int main(int argc, char **argv){
owner_t owner;
owner_init(&owner);
owner_notify(&owner);
}