C语言中的函数指针以及模拟面向对象
函数指针的概念
顾名思义,函数指针就是指向函数的指针,该指针的值是函数的入口。下面的代码时函数指针的一个基本实例。
#include <stdio.h>
int max_(int a, int b);
int max1_(int (*func_p)(int, int), int a, int b);
int main() {
int a = 10, b = 20;
// 定义一个函数指针p,并且p指向函数max_
int (*p)(int, int) = max_;
int ret = p(a, b);
printf("ret = %d\n", ret);
// 函数作为实参,函数指针作为形参
int ret1 = max1_(max_, a, b);
printf("ret1 = %d\n", ret1);
return 0;
}
int max_(int a, int b) {
// 返回两个整数中的较大值
return a>b?a:b;
}
int max1_(int (*func_p)(int, int), int a, int b) {
// func_p是函数指针,指向函数max_
return func_p(a, b);
}
将函数指针封装到结构体中,体现了面向对象编程的三大思想
- 1.封装:结构体内的函数指针成员作为结构体对象的行为,结构体内的非函数指针成员作为结构体对象的属性。
- 2.继承:Animal是一个结构体,Dog也是一个结构体,同时Dog有一个成员是Animal,这样Dog就继承了Animal的所有“属性”和“方法”(对于结构体来说,属性和方法都是结构体成员)
- 3.多态:Dog和Cat都继承了Animal。Animal有一个函数指针定义了Animal的叫声speak,Dog的叫声就是wang wang, 猫的叫声就是miao miao
更具体地,Animal.speak = speak(); Dog.animal.speak() = wang(); Cat.animal.speak() = miao();
wang()函数和miao()函数自己实现
#include <stdio.h>
#include <stdlib.h>
typedef struct Animal {
// 将函数指针封装在结构体中,当作类的方法成员
char* name;
void (*speak)(struct Animal *animal);
}Animal;
typedef struct Dog {
// 将父结构体封装在自己内部,实现继承
// Dog继承了Animal的所有属性和方法
Animal animal;
char sex; // 狗是公的还是母的;用'm', 'f'表示
}Dog;
typedef struct Cat {
// Cat继承了Animal类,并且有自己的属性color和方法sleep
Animal animal;
char* color;
void (*sleep)(struct Cat *cat); // 表示Cat对象在睡觉
}Cat;
void animal_speak(Animal* animal);
Animal* create_animal(char* name);
void dog_speak(Animal* animal);
Dog* create_dog(char* name, char sex);
void cat_speak(Animal* animal);
Cat* create_cat(char* name, char* color);
void cat_sleep(Cat* cat);
int main() {
// 创建一个Animal对象
Animal* animal = create_animal("BuGu");
animal->speak(animal);
// 创建一个Dog对象
Dog* dog = create_dog("Puppy", 'm');
dog->animal.speak(&(dog->animal));
printf("The sex of %s is %c\n", dog->animal.name, dog->sex);
// 创建一个Cat对象
Cat* cat = create_cat("Alice", "yellow");
cat->animal.speak(&(cat->animal));
printf("The color of %s is %s\n", cat->animal.name, cat->color);
cat->sleep(cat);
return 0;
}
void animal_speak(Animal* animal) {
// animal_speak函数传递给Animal对象的”函数指针“成员
printf("I am an animal and %s is speaking!\n", animal->name);
}
Animal* create_animal(char* name) {
// 创建一个Animal对象,返回指向此对象的指针
Animal* animal = (Animal*) malloc(sizeof(Animal));
animal->name = name;
animal->speak = animal_speak;
return animal;
}
void dog_speak(Animal* animal) {
// dog_speak函数传递给Dog对象的Animal成员的”函数指针“成员
printf("I am a dog and %s is wang wang wang!\n", animal->name);
}
Dog* create_dog(char* name, char sex) {
// 创建一个Dog对象,返回指向此对象的指针
Dog* dog = (Dog*)(malloc(sizeof(Dog)));
dog->animal.name = name;
dog->animal.speak = dog_speak;
dog->sex = sex;
return dog;
}
void cat_speak(Animal* animal) {
// cat_speak函数传递给Cat对象的Animal成员的”函数指针“成员
printf("I am a cat and %s is miao miao miao!\n", animal->name);
}
void cat_sleep(Cat* cat) {
// cat_sleep函数传递给Cat对象的”函数指针“成员sleep
printf("%s is sleeping!\n", cat->animal.name);
}
Cat* create_cat(char* name, char* color) {
// 创建一个Cat对象,返回指向此对象的指针
Cat* cat = (Cat*)(malloc(sizeof(Cat)));
cat->animal.name = name;
cat->animal.speak = cat_speak;
cat->color = color;
cat->sleep = cat_sleep;
return cat;
}