C语言实现面向对象的方法详解
结构体替代类
使用结构体来封装变量和函数,即可实现类似对象的功能。其中,结构体包含变量和函数指针,变量用于存储成员变量的值,函数指针用于实现成员函数的功能。而每个对象的变量是独立的,因此可以使用这种方法实现类似对象的功能。
下面是一个例子,以封装一个“人”的结构体为例:
typedef struct { char *name; int age; void (*speak)(const char *); } Person; void speak_func(const char *str) { printf("%s\n", str); } Person *new_person(char *name, int age) { Person *p = malloc(sizeof(Person)); p->name = name; p->age = age; p->speak = speak_func; return p; } void destroy_person(Person *p) { free(p); } void main() { Person *p = new_person("Tom", 18); p->speak("Hello world!"); //输出:Hello world! destroy_person(p); }
上述例子中,使用结构体Person封装了“人”的信息,其中包含两个成员变量和一个成员函数指针。函数指针speak指向函数speak_func,用于输出“人”的话语。通过new_person()函数创建一个新的“人”对象,人对象的变量是独立存储的。最后通过destroy_person()函数销毁“人”对象。
继承和多态
继承是面向对象的一个重要特性,允许子类继承父类的成员变量和成员函数,并可以自行定义新的成员变量和成员函数,因此可以实现代码的重用。
多态是面向对象中的另一个重要特性,指父类指针可以指向子类对象,从而调用子类重写的成员函数,实现代码的灵活性。
在C语言中,可以通过定义不同的结构体实现类的继承关系,并使用函数指针来实现多态。
下面是一个例子,以封装一个“动物”的父类和两个子类“狗”和“猫”为例:
typedef struct _Animal { const char *name; void (*speak)(struct _Animal *); } Animal; void speak(Animal *animal) { printf("%s speaks\n", animal->name); } typedef struct { Animal base; } Dog; void dog_speak(Dog *dog) { printf("%s barks\n", dog->base.name); } void init_dog(Dog *dog, const char *name) { dog->base.name = name; dog->base.speak = (void (*)(Animal *)) dog_speak; } typedef struct { Animal base; } Cat; void cat_speak(Cat *cat) { printf("%s meows\n", cat->base.name); } void init_cat(Cat *cat, const char *name) { cat->base.name = name; cat->base.speak = (void (*)(Animal *)) cat_speak; } void main() { Dog d; Cat c; init_dog(&d, "Dog"); init_cat(&c, "Cat"); Animal *pDog = (Animal*)(&d); Animal *pCat = (Animal*)(&c); pDog->speak(pDog); //输出:Dog barks pCat->speak(pCat); //输出:Cat meows }
上述例子中,定义了一个“动物”的父类和两个子类“狗”和“猫”。通过定义不同的结构体实现类的继承关系。其中,“动物”的父类包含成员变量name和成员函数指针speak,成员函数speak使用结构体指针作为参数,指向不同的子类实现。
通过init_dog()和init_cat()函数分别初始化“狗”和“猫”对象,其中“狗”对象继承了“动物”的父类,并自定义了成员函数speak()的实现,输出“狗”叫声;“猫”对象同理。
最后通过定义Animal类型的指针指向Dog和Cat实例实现多态。pDog和pCat指向不同的子类实例,调用speak函数时分别输出“狗”声和“猫”声。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
2020-12-23 git ------ fetch(获取)和 pull (拉取)的区别
2020-12-23 git ------ push(推送) 和 commit(提交) 的区别
2020-12-23 git ------ tortoiseGit 的使用