C面向对象与设计模式(一)

目录

一、概述

二、C++在类上的实现

2.1 什么是this 指针?

2.2 面向对象的三大特性

三、用C实现面向对象的三大特性

3.1 封装

3.2 继承

3.3 多态

四、总结


一、概述

       在做嵌入式软件开发过程中,当模块越来越多,代码越来越复杂,采用常规的的面向过程方法,容易使得代码混乱。通过合理的运用抽象、封装、继承和多态,更好的组织程序,从而很好地应对这种复杂性。C语言虽然是一门面向过程的语言,但我们知道,面向对象和面向过程是两种编程泛型,是一种解决问题的方法,与语言本身没有关系。不管是C还是C++,都只是一种工具,,有人用C写出大型且牛X的面向对象程序,也有人操着C++这把屠龙刀,却写着面向过程的程序。出于学习的目的,也为了和大家讨论学习,我决定总结自己平时在工作中用到的一些方法,共同探讨一下C在面向对象的一些方法以及设计模式。

二、C++在类上的实现

我们来看一个简单的C++类:

class Person{
public:
    void getName(){
        printf("%s\n",name);
    }
    void setName();
private:
    char name[20];
    int age; 

};

在分配内存之后,实际上对象只分配了数据成员的存储空间。因此实际上在内存分配上,其实类与结构体是相同的,即在内存分配上与下面这个结构体相同。

struct Person{

    char name[20];
    int age;
}

C++相同类的所有对象实际上都共用相同的代码段,有人会问,既然所有对象都调用相同的函数,那在调用成员函数时候,计算机是怎么选择去操作哪个对象的数据成员呢?可能学过C++的人都听说过this指针,虽然不一定知道它是个啥。

2.1 什么是this 指针?

C++每创建一个对象时候,会将该对象的起始地址赋值给this指针。例如之前的例子,类Person在编译完之后,其实getName编译成了:

void getName(* this){
    printf("%s\n",this->name);

}

如此可见,其实用C就可以写出面向对象的程序,只不过是没有C++那般方便,需要绕一些弯路,我们可以模仿this指针来实现。

2.2 面向对象的三大特性

三大特性:封装、继承、多态

我们知道很多设计模式都基于这三大特性来实现的,接下来我来简单介绍如何用C语言来实现这三大特性

三、用C实现面向对象的三大特性

3.1 封装

类有数据成员和成员函数,即数据与方法,在C语言中,我们可以配合结构体以及函数指针来实现,简单实现如下:(这里主要是讲思想,如果已经理解思想,而更追求结果,可直接跳转到:点击这里)

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef struct Person Person;
struct Person{
    void (*whoIam)(Person *this);
    void (*setName)(Person *this,char * name);

    char name[20];
    int age; 
};

void whoIam(Person *this){
    printf("I am a %s\n",this->name);
}
void setName(Person *this, char * name){
    strcpy(this->name, name);
}
void init(Person* obj){
    obj->setName = setName;
    obj->whoIam = whoIam;
}

int main(){
    Person* man,*girl;
    //实例化对象
    man = (Person*)malloc(sizeof(Person));
    girl = (Person*)malloc(sizeof(Person));
    init(man);
    init(girl);
    //成员函数的调用
    man->setName(man,"man");
    girl->setName(girl,"girl");
    man->whoIam(man);
    girl->whoIam(girl);
    return 0;
}

     从上面的代码来看,结构体person类似于C++的类,封装了成员函数whoIam和setName,有数据成员name 和age;这里着重介绍C面向对象的思想,关于更好的封装,请看后续的的教程。

3.2 继承

废话不多说,直入代码:

typedef struct Girl Girl;
struct Girl{
    Person father;
    void (*buildChild)(Girl *this);
};

void buildChild(){
    printf("I can build a baby\n");
}

void Girl_init(Girl* obj){
    //构造基类
    init(&(obj->father));
    obj->buildChild = buildChild;
}
int main(){
    Girl* girl;
    //实例化对象
    girl = (Girl*)malloc(sizeof(Girl));
    Girl_init(girl);
    //调用父类方法
    girl->father.setName(girl,"xiaohong");
    girl->father.whoIam(girl);
    //调用子类新方法
    girl->buildChild(girl);
    return 0;
}

继承可直接在新类,结构体内定义父类的一个成员,如上程序,由程序可见,新类Girl 继承Person,拥有了Person的属性和方法,同时又增加了自己新的能力,buildChild,即女孩是人的一种,但她会造小孩,这是她新的能力。

3.3 多态

上面介绍了封装、继承,下面说说多态。直接上程序:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef struct Person Person;
//人类
struct Person{
    void (*whoIam)(Person *this);
    void (*setName)(Person *this,char * name);
    void (*buildChild)(Person *this);

    char name[20];
    int age; 
};
void whoIam(Person *this){
    printf("I am %s\n",this->name);
}
void setName(Person *this, char * name){
    strcpy(this->name, name);
}
void init(Person* obj){
    obj->setName = setName;
    obj->whoIam = whoIam;
}
//女人类
typedef struct Girl Girl;
struct Girl{
    Person father;
    void (*buildChild)(Girl *this);
};
void Girl_buildChild(){
    printf("I can build a baby one month\n");
}
void Girl_init(Girl* obj){
    //构造基类
    init(&(obj->father));
    obj->buildChild = Girl_buildChild;
    obj->father.buildChild = obj->buildChild;
}

//男人类
typedef struct Man Man;
struct Man{
    Person father;
    void (*buildChild)(Man *this);
};

void man_buildChild(){
    printf("I can build tens of thousands of baby every day\n");
}

void Man_init(Man* obj){
    //构造基类
    init(&(obj->father));
    obj->buildChild = man_buildChild;
    obj->father.buildChild = obj->buildChild;
}

int main(){
    Person* zhang;
    //实例化为男人
    zhang = (Man*)malloc(sizeof(Man));
    Man_init(zhang);
    zhang->buildChild(zhang);
    //实例化为女人
    zhang = (Girl*)malloc(sizeof(Girl));
    Girl_init(zhang);
    zhang->buildChild(zhang);
    return 0;
}

上面是完整代码,运行结果如下:

I can build tens of thousands of baby every day
I can build a baby one month

首先“人”类都拥有造孩子的能力,所以“男人”和“女人”类都继承于人,所以都会造小孩,但是“男”和“女”各自造小孩的能力有有所差异,在主函数中,我们定义一个基类指针“小张同学”,小张同学原本是个男人,但后来做了变性手术,科技太强大,就连生孩子的能力也变了。以上即用C实现了类似于C++的虚函数特性,多态中的一种。

四、总结

以上介绍了用C实现面向对象编程的思想,下篇我将介绍一种封装的比较好的C面向对象开发库的运用。如果本文对你理解面向对象编程思想有点作用,别忘了点个赞哟......

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值