bC 语言也可以面向过程的;没有错。就是通过将结构体和指针结合,所以C 语言也可以是面向对象的。
案例:
这里void (*log_func)(logger* this, const char* msg);定义了一个名为log_func
的函数指针,该函数接受一个类型为logger
的指针和一个指向常量字符的指针作为参数,并且没有返回值。
/// log.h
#ifndef _LOG_H_
#define _LOG_H_
typedef struct logger logger;
typedef void (*log_func)(logger* this, const char* msg);
typedef struct logger {
log_func log;
} logger;
void common_log_init(logger** args);
void common_log_uninit(logger* args);
#endif // _LOG_H_
/// log.c
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
static void common_log(logger* this, const char* msg) {
(void)this;
printf("%s\n", msg);
}
void common_log_init(logger** args) {
if (!args) {
perror("args is nullptr");
return;
}
*args = (logger*)malloc(sizeof(logger));
if (!*args) {
perror("out of memory");
return;
}
(*args)->log = common_log;
}
void common_log_uninit(logger* args) { free(args); }
/// main.c
#include "log.h"
int main() {
logger* log;
common_log_init(&log);
log->log(log, "test msg");
common_log_uninit(log);
return 0;
}
Thinkpad:~/debug$ gcc log.c main.c -o log
Thinkpad:~/debug$ ./log
test msg
2、继承与多态
C 语言结构体也可以继承,用于复用代码。比如我们希望在 logger 能够记录模块信息,则可以继承 logger 结构体,复用 log 函数指针,然后添加新的成员。
// log.h
...
void mylog_init(logger** args, const char* module);
void mylog_uninit(logger* args);
...
/// mylog.c
#include <stdio.h>
#include <stdlib.h>
#include &#