类和对象实际上是C++中的概念,但是在嵌入式C语言中,有时的确需要定义类和对象来方便我们的程序设计,因此我们有时候也借鉴一些C++的思想。
比如我们要做车窗控制,我们可以建立一个车窗类,然后再分别定义左前、右前,左后和右后这四个车窗对象。
建立一个车窗类
typedef struct
{
st_win_drv Drv;
st_win_cmd Cmd;
st_win_st St;
st_win_lock Lock;
st_win_runtime Runtime;
st_win_block Block;
……
} st_win;
建立一个车窗类的目的是,为了把车窗相关参数都提炼出来,也就是车窗的通用属性,都归入到整个车窗类当中。这样,相当于把整个车窗的所有相关参数都打包规整到了一起,再采用指针(*)或者传址(&),那么对于这些参数的管理、调用和传递都会方便很多。
这里再解释一下,这几个参数的具体含义:
st_win_drv:车窗驱动,主要用于辨别驱动对象;
st_win_cmd:车窗接收指令,比如手动升降窗、自动升降窗等;
st_win_st:车窗当前的运动状态;
st_win_lock:车窗锁止保护,主要用于车窗电机的反转保护;
st_win_runtime:车窗运动时间;
st_win_block:车窗电机堵转;
关于车窗的实际参数还远不止这些,有时还需要根据某些特殊功能,做一些特殊的参数设计。这里就不一一列举了。当然,关于类的设计,实际上这里还是数据结构的设计,也要注意一些基本原则。
数据结构的设计原则
不要设计面面俱到的数据结构。相关的一组信息,才是构成一个结构体的基础,结构的定义应该可以明确地描述一个对象,而不是一组相关性不强的数据集合。设计结构时应力争使结构代表一种现实事务的抽象,而不是同时代表多种。结构中的各元素应代表同一事务的不同层面,而不应把描述没有关系或关系很弱的不同事务的元素放到同一结构中。
你像这里,就不适合把车窗控制开关的参数揉到这个车窗类里去。
其实,上面的车窗类还并不是真正意义上的类,还只能算是个结构体。因为在这个所谓的“车窗类”里,还只有数据成员,而并没有成员函数。下面我们就将为其添加、设计相应的成员函数。
将C语言中的结构体演变成C++中的类
typedef struct
{
st_win_drv Drv;
st_win_cmd Cmd;
st_win_st St;
st_win_lock Lock;
st_win_runtime Runtime;
st_win_block Block;
……
st_win_fun_key *Key;
st_win_fun_drv *Drv;
st_win_fun_lin_study *LinStudy;
……
} st_win;
添加成员函数,由于C语言中并不能在结构体中定义函数,但是我们却可以在其中定义函数指针。这样我们的结构体里,就有了成员函数。通过这种方式,实际上我们就完成了由结构体到类的转变。
st_win_fun_key *Key;
st_win_fun_drv *Drv;
st_win_fun_lin_study *LinStudy;
解释一下这里添加的三个函数的含义:
st_win_fun_key:检测车窗控制按键状态的调用函数;
st_win_fun_drv:检测车窗驱动状态的调用函数;
st_win_fun_lin_study :车窗通过LIN总线学习位置的功能函数;
以上就完成了整个车窗类的定义,最后我们再通过它来定义各个车窗对象。
定义车窗对象
根据定义的车窗类,可以很方便的定义车窗对象。
比如定义一个左前车窗(驾驶侧),
st_win DDWin;
左前车窗初始化,
DDWin =
{
{0},{0},{0},{0},{0},{0},
&WinKeyFun,
&WinDrvFun,
&WinLinStudyFun,
};
其他各个车窗以此类推,这完成整个车窗类和对象的设计。