面向对象是一种设计思想与方法,特点为封装、继承和多态。一般认为C语言是面向过程的语言,C++是面向对象的语言。但是在资源限制的嵌入式系统中,使用C语言面向对象编程,程序运行效率更高1

封装

封装的思想为把数据和操作数据的函数放到一个类中。C语言中结构体用来保存数据,含结构体指针作为形参的函数操作数据,结构体定义和函数声明放到.h,函数实现放到.c,.h与.c文件可放到一个文件夹下作为一个功能模块。

shape.h

/*文件名称shape.h*/
#ifndef SHAPE_H
#define SHAPE_H
#include <stdint.h>

// Shape 的属性
typedef struct {
    int16_t x; 
    int16_t y; 
} Shape;

// Shape 的操作函数,接口函数
void Shape_ctor(Shape * const me, int16_t x, int16_t y);
void Shape_moveBy(Shape * const me, int16_t dx, int16_t dy);
int16_t Shape_getX(Shape const * const me);
int16_t Shape_getY(Shape const * const me);

#endif /* SHAPE_H */

shape.c

/*文件名称shape.c*/
#include "shape.h"

// 构造函数
void Shape_ctor(Shape * const me, int16_t x, int16_t y)
{
    me->x = x;
    me->y = y;
}
void Shape_moveBy(Shape * const me, int16_t dx, int16_t dy) 
{
    me->x += dx;
    me->y += dy;
}

// 获取属性值函数
int16_t Shape_getX(Shape const * const me) 
{
    return me->x;
}
int16_t Shape_getY(Shape const * const me) 
{
    return me->y;
}

main.c

/*文件名称 main.c*/
#include "shape.h"  /* Shape class interface */
#include <stdio.h>  /* for printf() */
int main() 
{
    Shape s1, s2; /* multiple instances of Shape */
    Shape_ctor(&s1, 0, 1);
    Shape_ctor(&s2, -1, 2);
    printf("Shape s1(x=%d,y=%d)\n", Shape_getX(&s1), Shape_getY(&s1));
    printf("Shape s2(x=%d,y=%d)\n", Shape_getX(&s2), Shape_getY(&s2));
    Shape_moveBy(&s1, 2, -4);
    Shape_moveBy(&s2, 1, -2);
    printf("Shape s1(x=%d,y=%d)\n", Shape_getX(&s1), Shape_getY(&s1));
    printf("Shape s2(x=%d,y=%d)\n", Shape_getX(&s2), Shape_getY(&s2));
    return 0;
}

继承

继承指的是基于现有的类定义新类。C语言实现,通过把基类放到继承类的第一个数据成员的位置实现。

rect.h

/*文件名称 rect.h*/
#ifndef RECT_H
#define RECT_H
#include "shape.h" // 基类接口

// 矩形的属性
typedef struct {
    Shape super; // 继承 Shape
    // 自己的属性
    uint16_t width;
    uint16_t height;
} Rectangle;

// 构造函数
void Rectangle_ctor(Rectangle * const me, int16_t x, int16_t y,
                    uint16_t width, uint16_t height);
#endif /* RECT_H */

rect.c

/*文件名称 rect.c*/

#include "rect.h"
// 构造函数
void Rectangle_ctor(Rectangle * const me, int16_t x, int16_t y,
                    uint16_t width, uint16_t height)
{
    /* first call superclass’ ctor */
    Shape_ctor(&me->super, x, y);
    /* next, you initialize the attributes added by this subclass... */
    me->width = width;
    me->height = height;
}

main.c

/*文件名称 main.c*/
#include "rect.h"  
#include <stdio.h> 
int main() 
{
    Rectangle r1, r2;
    // 实例化对象
    Rectangle_ctor(&r1, 0, 2, 10, 15);
    Rectangle_ctor(&r2, -1, 3, 5, 8);
    printf("Rect r1(x=%d,y=%d,width=%d,height=%d)\n",
           Shape_getX(&r1.super), Shape_getY(&r1.super),
           r1.width, r1.height);
    printf("Rect r2(x=%d,y=%d,width=%d,height=%d)\n",
           Shape_getX(&r2.super), Shape_getY(&r2.super),
           r2.width, r2.height);
    // 注意,这里有两种方式,一是强转类型,二是直接使用成员地址
    Shape_moveBy((Shape *)&r1, -2, 3);
    Shape_moveBy(&r2.super, 2, -1);
    printf("Rect r1(x=%d,y=%d,width=%d,height=%d)\n",
           Shape_getX(&r1.super), Shape_getY(&r1.super),
           r1.width, r1.height);
    printf("Rect r2(x=%d,y=%d,width=%d,height=%d)\n",
           Shape_getX(&r2.super), Shape_getY(&r2.super),
           r2.width, r2.height);
    return 0;
}

多态

C++使用虚函数实现多态。C语言实现稍显复杂。多态以封装和继承为前提,不同的子类对象调用相同的方法,产生不同的执行结果。


  1. 嵌入式 C 语言的高级用法,面向对象 ↩︎