嵌入式软件开发中,虽然很多的开发工具已经支持C++的开发,但是因为有时考虑运行效率和编程习惯,还是有很多人喜欢用C来开发嵌入式软件。Miro Samek说:“我在开发现场发现,很多嵌入式软件开发者(绝大多数是电子工程师)都有工作背景而且他们常常不喜欢用C++。”【1】

面向对象编程(OOP)是一种方法,而不依赖于某特定语言。一般认为,OOP只能使用面向对象的语言,如Smalltalk、C++或Java等固有支持OOP的语言。但是,OOP并不依赖于特殊的语言,只要实现了OOP的封装、继承和多态性这三大基本特性,使用非固有支持面向对象的语言,也可以进行面向对象的编程。

面向对象编程方法的三大基本特性是:

  • 封装性---封装数据(属性)与函数(方法)到类中的能力;
  • 继承性---基于已有的类定义新类的能力;
  • 多态性---在运行时具有一致接口的对象相互替换的能力。

虽然这些特性与面向对象语言有关,但几乎可以用任何语言实现面向对象的这三大基本特性,包括C语言和汇编语言等。事实上,不管实现语言为何,任何大的软件系统几乎都会以某种形式使用抽象(封装)、继承或多态性。

1.C语言的封装

1.1 封装的本质

在C++中,一个类中包括属性和方法,声明一个类例子如下:

class A {
int n; //属性
A(); //构造函数
void function1(int x){...}; //方法
}

在C++中,用A生成两个对象a1和a2时,如下:

A a1 = new A();
A a2 = new A();

对于非模板类A,在内存中,对所有的对象,方法function1只有一个拷贝,而对每个对象,都有自己独立的一份属性拷贝,也就是有多个属性拷贝,所谓创建一个对象,也就是创建一套属性。

调用a1.function1()和a2.function1()时,每个对象使用自己的属性n1和n2,而方法代码在内存中是同一套。这就相当于调用functin1(n1,x)和function1(n2,x)。

在C语言实现中,把所有的属性放到一个结构中,所有方法中第一个参数用一个指向自己属性结构的一个指针me, 如下:
function1(struct *me, ...);
这个方法对所有对象有用,具体对哪个对象的属性操作,可以用me来区分。

1.2 具体例子

生成两个文件person.h和person.c,定义一个Person结构类型(也就是类名称),把属性放到结构中方法中的第一个参数me是Person的引用指针

pers1.2on.h文件:
在头文件中以结构定义类成员属性,声明构造方法和析构方法,声明public方法。

#ifndef PERSON_H
#define PERSON_H /*1.定义类成员属性(没有隐藏)*/
typedef struct PersonTag {
String name__; /*属性*/
uint8_t age__; /*属性*/
}Person; /*2.声明构造和析构函数*/
void Person_Ctor(Person *me, uint8_t age);/*第一个参数指向属性*/
void Person_Xtor(Person *me);/*第一个参数指向属性*/ /*3.声明public方法*/
void Person_setName(Person *me, String name);/*第一个参数指向属性*/
String Person_getName(Person *me);/*第一个参数指向属性*/ /*4.声明private方法(要在person.c文件中声明)*/ #endif

person.c文件:
在.c文件中声明private方法,并实现所有的方法。

#include "person.h"

/*1.声明private方法, 用static修饰*/
static void Person_setAge(Person *me, uint8_t age);/*第一个参数指向属性*/
static uint8_t Person_getAge(Person *me);/*第一个参数指向属性*/ /*2.实现构造和析构函数*/
void Person_Ctor(Person *me, uint8_t age) {
me->age__ = age;
}
void Person_Xtor(Person *me) {
...
} /*3.实现public方法*/
void Person_setName(Person *me, String name) {
me->name__ = name;
}
String Person_getName(Person *me) {
return me->name__;
} /*4.实现private方法*/
void Person_setAge(Person *me, uint8_t age) {
me->age__ = age;
}
uint8_t Person_getAge(Person *me) {
return me->age__;
}

app.c中使用Person类:

#include "person.h"  /*包含头*/
void main() {
String tmp;
Person l_ps1; /*创建一个实例,实际就是一个属性*/
Person l_ps2; /*创建另一个实例,实际就是另一个属性*/ Person_Ctor(l_ps1, 30); /*显式调用构造函数*/
Person_setName(l_ps1,"张三"); /*使用其public方法*/
tmp = Person_getName(l_ps1); /*使用其public方法*/ Person_Ctor(l_ps2, 30); /*使用其public方法*/
Person_setName(l_ps2, "李四"); /*使用其public方法*/
tmp = Person_getName(l_ps2); /*使用其public方法*/
}

2.C语言的继承

Student继承自Person, 继承类属性结构的第一个参数指向父类属性,这样可以满足Liskov替换原则

student.h文件:
在头文件中以结构定义类成员属性,并声明构造、析构函数和public方法。

#ifndef STUDENT_H
#define STUDENT_H
#include "person.h" /*包含父类头*/ /*1.定义类属性(没有隐藏)*/
typedef struct StudentTag {
Person super; /*第一个参数指向父类Person,继承父类属性*/
uint8_t code__; /*子类添加的属性*/
}Student; /*2.声明构造和析构方法*/
void Student_Ctor(Student *me, uint8_t code);
void Student_Xtor(Student *me); /*3.声明public方法*/
void Student_setCode(Student *me, uint8_t code);
uint8_t Student_getCode(Student *me); /*4.声明private方法(在.c文件中声明)*/ #endif

student.c文件:
在.c文件中声明private方法,实现所有的构造方法和析构方法,实现所有的public和private方法。

#include "student.h"

/*1.声明private方法*/
static void XXX(Student *me, ...); /*2.构造和析构方法实现*/
void Student_Ctor(Student *me, String name, uint8_t code) {
Person_Ctor((Person*)me, name);/*先调用父类构造函数*/
me->code__ = code;
}
void Person_Xtor(Person *me) {
...
} /*3.public方法实现*/
void Student_setCode(Student *me, uint8_t code) {
me->code__ = code;
}

app.c中使用Student类:

#include "Student.h"  /*包含头*/
void main() {
String tmp;
Student l_st1; /*创建一个实例,实际就是一个属性*/
Student l_st2; /*创建另一个实例,实际就是另一个属性*/ Student_Ctor(l_st1, "张三, 25); /*显式调用构造函数*/
Student_setCode(l_st1, 30); //使用其public方法
tmp = Student_getCode(l_st1); //使用其public方法
}

3.C语言的多态性

利用C语言的万能指针void *p可以实现多态。略。

4.总结

用C语言可以实现面向对象的三大特性,适合于嵌入式系统的编程,QP的C版本就是这样实现的。现在很多的开源软件,包括postgreSQL、GObject等都采用C语言实现面向对象的方法。采用这个方法,使程序具有更好的可读性、可扩展性,同时保持了C语言的高效性。

基于C语言的面向对象编程的更多相关文章

  1. C 语言实现面向对象编程

    转载 https://blog.csdn.net/onlyshi/article/details/81672279 C 语言实现面向对象编程1.引言面向对象编程(OOP)并不是一种特定的语言或者工具, ...

  2. 一步步分析:C语言如何面向对象编程

    这是道哥的第009篇原创 一.前言 在嵌入式开发中,C/C++语言是使用最普及的,在C++11版本之前,它们的语法是比较相似的,只不过C++提供了面向对象的编程方式. 虽然C++语言是从C语言发展而来 ...

  3. 真的可以啊,用C语言实现面向对象编程O O P!C语言真的无所不能~

    解释区分一下C语言和OOP 我们经常说C语言是面向过程的,而C++是面向对象的,然而何为面向对象,什么又是面向过程呢?不管怎么样,我们最原始的目标只有一个就是实现我们所需要的功能,从这一点说它们是殊途 ...

  4. Python源代码 -- C语言实现面向对象编程(基类&派生类&多态)

    背景 python是面向对象的解释性语言.然而python是通过C语言实现的,C语言怎么跟面向对象扯上了关系? C语言能够实现面向对象的性质? 原文链接:http://blog.csdn.net/or ...

  5. 真的可以,用C语言实现面向对象编程OOP

    ID:技术让梦想更伟大 作者:李肖遥 解释区分一下C语言和OOP 我们经常说C语言是面向过程的,而C++是面向对象的,然而何为面向对象,什么又是面向过程呢?不管怎么样,我们最原始的目标只有一个就是实现 ...

  6. Objective-C语言介绍 、 Objc与C语言 、 面向对象编程 、 类和对象 、 属性和方法 、 属性和实例变量

    1 第一个OC控制台程序 1.1 问题 Xcode是苹果公司向开发人员提供的集成开发环境(非开源),用于开发Mac OS X,iOS的应用程序.其运行于苹果公司的Mac操作系统下. 本案例要求使用集成 ...

  7. C语言进行面向对象编程

    http://blog.csdn.net/dadalan/article/details/3983888 http://blog.163.com/zhqh43@126/blog/static/4043 ...

  8. c语言实现面向对象编程

    1.通用校验器接口(validator.h) #ifndef VALIDATOR_H_INCLUDED #define VALIDATOR_H_INCLUDED #include<stdbool ...

  9. 云风:我所偏爱的C语言面向对象编程范式

    面向对象编程不是银弹.大部分场合,我对面向对象的使用非常谨慎,能不用则不用.相关的讨论就不展开了. 但是,某些场合下,采用面向对象的确是比较好的方案.比如 UI 框架,又比如 3d 渲染引擎中的场景管 ...

随机推荐

  1. 浅谈App原生开发、混合开发及HTML5开发的优劣

    App混合开发(英文名:Hybrid App),是指在开发一款App产品的时候为了提高效率.节省成本即利用了原生的开发技术还应用了HTML5开发技术,是原生和HTML5技术的混合应用.目前App的开发 ...

  2. 微软发布Azure Stack第一个技术预览版

    为了提升商业灵敏度和加快创新步伐,各个企业都在迅速地转向云服务.在微软,我们已经见到微软智能云Azure的飞速发展和使用,每月我们都有近十万的新增订阅量.然而,我们也了解到还有很多企业在完全移到公有云 ...

  3. pt-find使用

    查找MySQL的表,并且做一些操作,基本语法就如下: pt-find [OPTIONS] [DATABASES] (1)查找一天前建立的MyISAM 引擎的表 [root@mxqmongodb2 bi ...

  4. base64编码加密图片和展示图片

    base64是当前网络上最为常见的传输8Bit字节代码的编码方式其中之一.base64主要不是加密,它主要的用途是把某些二进制数转成普通字符用于 网络传输.由于这些二进制字符在传输协议中属于控制字符, ...

  5. 永中Office的ibus输入法问题

    我在永中Office下无法调用ibus输入法,但是在其他窗口中都没有问题,如:gVIM,LeafPad,OpenOffice等等.我按照网上的方法在.bashrc文件中也添加了以下内容,可是还是不行. ...

  6. 两个List中的补集

    /** * 获取两个List的不同元素 * @param list1 * @param list2 * @return */ private static List getDiffrent(List ...

  7. CF#538(div2) B. Yet Another Array Partitioning Task 【YY】

    任意门:http://codeforces.com/contest/1114/problem/B B. Yet Another Array Partitioning Task time limit p ...

  8. Linux入门基础介绍

    概述: 1. linux是一个开源.免费的操作系统,其稳定性.安全性.处理多并发已经得到业界的认可,目前很多企业级的项目        都会部署到Linux/unix系统上. 2. 常见的操作系统(w ...

  9. MyBatis(10)逆向工程

    什么是逆向工程? 在学习的过程中会发现,需要我们写大量的sql语句 此时mybaatis官方为我们提供逆向工程可以针对单表自动生成的mybatis执行所需要的代码     使用方法:    MyBat ...

  10. AngularJS简介-起步阶段

    AngularJS 是一个为动态WEB应用设计的结构框架,提供给大家一种新的开发应用方式,这种方式可以让你扩展HTML的语法,以弥补在构建动态WEB应用时静态文本的不足,从而在web应用程序中使用HT ...