前言
这几天正在学习C++, 学到了面向对象, 突然想到前几天写的期末项目, 自己就已经潜移默化的运用了面向对象的思想. 于是就开始思考, 能否在C语言中实现面向对象编程. C语言本身不支持面向对象, 这给实现过程带来了很多的麻烦, 但好在也能通过一些方法硬造出来.
类和对象
1. 创建类
C++中, 类通过class来实现. 在C语言中, 可以通过结构体模拟class来实现类的包装, 我们以实现一个不可变长的栈为例:
typedef struct {
int* content;
int top;
int size;
} Stack;
此时Stack结构体中包含了栈相关的数据
关于类方法, 由于结构体中不能放置函数, 因此需另寻方法. 首先想到的是函数指针, 以pop为例:
void pop();
typedef struct{
int *content;
int top;
int size;
void (*pop)();
} Stack;
聪明的你应该发现了问题: pop() 函数的实现需要知道Stack中的content
及top
数据, 而直接通过.
调用函数指针时, 函数无法知道是哪个Stack类型的变量调用了他, 因此必须通过参数的方式告知函数是哪个Stack对象调用了他, 因此这里需要把方法写在结构体外面:
typedef struct{
int *content;
int top;
int size;
} Stack;
// Stack.pop()
void stack_pop(Stack *s);
这里在方法名前加上stack_
防止命名冲突.
由于C语言中无法声明一个变量是private的还是public的, 因此就全靠自觉了()
补全Stack相关的操作:
```c
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
// class Stack
// private
typedef struct {
int* content;
int top;
int size;
} Stack;
// public
Stack stack_init(int size);
void stack_quit(Stack* s);
bool stack_push(Stack* s, int target);
bool stack_pop(Stack* s);
int stack_top(const Stack* s);
void stack_is_empty(const Stack* s);
void stack_is_full(const Stack* s);
// class
此处传入的Stack变量为指针形式可以加快运行速度, 节省内存, 并使函数能够修改传入结构体的值.
在声明Stack类型对象后, 需调用stack_init
函数来初始化对象; 在对象不需要再使用时, 需调用stack_quit
函数来释放对象:
int main(){
Stack *stack_1;
stack_1 = stack_init(100);
...
stack_quit(stack_1);
}
Stack *stack_init(int size){
Stack *s = (Stack *)malloc(sizeof(Stack));
s -> content = (int *)malloc(sizeof(int) * size);
s -> size = size;
s -> top = 0;
return s;
}
void stack_quit(Stack *s){
free(s -> content);
free(s);
}
相较于C++, 有一个方便之处: 传入参数名不需要保证和类中变量名相同了. 这使得类中变量的命名更加自由了.
继承
假设我们需要实现一个类, 能够实现栈的功能, 并记录每次更改的时间:
// class timer
// private
typedef struct{
Stack *stack;
time_t time;
} Timer;
// public
Timer timer_init(int size);
void timer_get_time(Timer *t);
void timer_quit(Timer *t);
// class
可以看到, Timer类内包含Stack类的对象. 如果想要使用Stack类的方法, 只需要用.
取出Timer中的stack, 对其使用Stack类的方法. 例如timer_init
就可以使用stack_init
方法来初始化其中的Stack对象:
Timer timer_init(int size){
Timer t;
t -> stack = (Stack *)malloc(sizeof(Stack));
t -> stack = stack_init(size);
t -> time = 0;
return t;
}
void timer_quit(Timer *t){
stack_quit(t -> stack);
free(t -> stack);
free(t);
}
也可以使用Stack中的其他类方法:
int main(){
Timer *timer_1;
timer_1 = timer_init(100);
stack_push(timer_1.stack, 114514);
timer_get_time(timer_1);
return 0;
}
多态
考虑Stack的另一个子类:
// class
// private
typedef struct{
Stack *stack;
char *msg;
} Msger;
// class
如果想要实现一个函数, 能够打印出Msger中的msg和Timer中的time, 应该如何实现?
C语言中, 想要实现像这样的多态, 似乎只能通过声明多个函数:
void timer_print(Timer *t){
printf("Time = %ud", t -> time);
}
void msger_print(Msger *m){
printf("Message: %s", m -> msg);
}
只能算勉强实现了多态.
标签:int,void,timer,stack,OOP,使用,C语言,Stack,size From: https://www.cnblogs.com/blog-lxx11451/p/18016297学生党的第一篇文章(), 想必有很多疏漏之处, 恳请不吝赐教