在一些比较底层的软件中,只能使用C语言开发,但是又要利用面向对象设计的优越性,如何用C来达到面向对象的效果呢?
面向对象的特点即是继承,封装和多态。对于封装,在C语言中一般使用static方式来实现,这时更多地体现的是一种”模块化”的思想。
继承的实质就是在子类中包含父类的成员,而多态的实质就是虚函表的查找。使用C语言就可以模拟这种过程,从而实现OO编程。
No code I say a j8?
看代码。
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
enum animal_type{
ANIMAL_DOG,
ANIMAL_CAT,
ANIMAL_ABSTRACT,
};
typedef struct animal{
int animalID;
void* other_property;
void (*run)();
void (*say)();
void (*proc_property)(void*);
void (*fini)(struct animal*);
}Animal;
void animal_fini(Animal* animal){
free(animal->other_property);
}
void animal_init(Animal* animal){
animal->animalID = ANIMAL_ABSTRACT;
animal->fini = animal_fini;
}
typedef struct dog_property{
int legs_num;
}DOG_PROPERTY;
void dog_run(){
cout<<"dog is running"<<endl;
}
void dog_say(){
cout<<"wangwang!"<<endl;
}
void dog_proc_property(void* property){
DOG_PROPERTY* p = (DOG_PROPERTY*)property;
cout<<"I have "<<p->legs_num<<" legs"<<endl;
}
void dog_init(Animal* animal){
animal_init(animal);
DOG_PROPERTY* property = (DOG_PROPERTY*)malloc(sizeof(DOG_PROPERTY));
property->legs_num = 4;
animal->animalID = ANIMAL_DOG;
animal->other_property = property;
animal->run = dog_run;
animal->say = dog_say;
animal->proc_property = dog_proc_property;
}
typedef struct cat_property{
char eyescolor[16];
}CAT_PROPERTY;
void cat_run(){
cout<<"cat is running"<<endl;
}
void cat_say(){
cout<<"miaomiao"<<endl;
}
void cat_proc_property(void* property){
CAT_PROPERTY* p = (CAT_PROPERTY*)property;
cout<<"my eyes' color is "<<p->eyescolor<<endl;
}
void cat_init(Animal* animal){
animal_init(animal);
CAT_PROPERTY* p = (CAT_PROPERTY*)malloc(sizeof(CAT_PROPERTY));
strcpy(p->eyescolor, "blue");
animal->animalID = ANIMAL_CAT;
animal->other_property = p;
animal->run = cat_run;
animal->say = cat_say;
animal->proc_property = cat_proc_property;
}
int main()
{
int num = 2;
Animal animals[num];
dog_init(animals);
cat_init(animals + 1);
for(int i = 0;i < num;i++){
//多态就在这里发生了
animals[i].run();
animals[i].say();
animals[i].proc_property(animals[i].other_property);
animals[i].fini(animals + i);
}
return 0;
}
可以把animal的部分提取成公共头文件,并把dog和cat的相关代码分开,这里为了方便写到一块了。
类似的写法可以在写Linux设备驱动时见到,写一个设备驱动,就要写设备相关的read,write等函数,类似于override父类的相关函数。
面向对象的本质其实就是,一个对象(一块内存)和对象上所绑定的一组操作(一组函数)。
C语言NB之处就是可以随心所欲操纵内存(这也是我喜欢C/C++的原因),因此使用C语言做OO完全不虚。