在我们的印象中,C语言是一个面向过程的语言。应该是和面向对象没有什么关系的。但是在我们的实际开发中,如果我们真的决定使用C语言来完成一个大型的项目的化。纯函数式的编程,纯面向过程式的设计还是会让代码很难维护和理解的。
所以一般的C语言项目中是或多或少会去尝试一些面向对象的设计的。那么用C 语言怎么实现面向对象呢?
结构体+函数指针。基本就是这个套路了。
比如我们想要定义一个Person
类。那么用Java的话,我们一般是这样定义的:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
使用的时候我们只需要这样使用即可
Person person = new Person("jerry", 27);
String name = person.getName();
int age = person.getAge();
person.setAge(50);
person.setName("tom");
那如果我们有C 语言的实现是怎么样呢?
typedef struct _person{
char name[128];
int age;
void (*setName)(struct _person * person, char* name);
void (*setAge)(struct _person * pseron,int age);
char *(*getName)(struct _person * person,int *len);
int (*getAge)(struct _person * pseron);
}Person;
static void setName(struct _person * person, char* name){
if(person == NULL)
return;
memcpy(person->name, name, strlen(name));
return;
}
static void setAge(struct _person * person,int age){
if(person == NULL)
return;
person->age = age;
return;
}
static char * getName(struct _person * person, int *len){
if(person == NULL)
return NULL;
*len = strlen(person->name);
return person->name;
}
static int getAge(struct _person * person){
if(person == NULL)
return -1;
return person->age;
}
Person * Person_new(char * name, int age){
Person * person = NULL;
person = (Person *)malloc(sizeof(Person));
memset(person, 0, sizeof(Person));
person->getAge = getAge;
person->getName = getName;
person->setName = setName;
person->setAge = setAge;
memcpy(person->name, name, strlen(name));
person->age = age;
return person;
}
void Person_delete(Person * person){
if(person == NULL)
return;
free(person);
return;
}
使用时代码这样编写
Person * person = Person_new("jerry", 27);
person->setAge(person, 50);
person->getAge(person);
int len;
printf("person name : %s, age: \n", person->getName(person, &len), person->getAge(person));
Person_delete(person);
person = NULL;
然后我们发现,在Java中我们不需要把person
本身作为参数传递给Person
类的方法。但是再C里面我们需要为每一个函数传递一个Person
结构体指针。因为在函数中如果操作Person
结构体的成员的话,必须要能访问到person
,所以我们要把这个结构体指针传入函数中。这样一看,感觉好像C 语言实现起来好别扭,其实不然。其实在Java 中如果我们要访问Person
类的成员,我们同样需要一个指向Person
对象的引用。只不过这一引用表现的比较含蓄,它就是this
关键字。而传入引用这个动作也不用我们在代码中显示的写出来。但我们完全可以把他们看成是一样的。Java的this
就是C里面的 person
。这样是不是整个逻辑就通了。
用C语言来表达面向对象的思想就是这么简单。没有太大的花头。