C中的多态函数参数/返回值

Joe*_*l B 1 c polymorphism c89

我正在使用嵌入式微控制器,我必须将多种类型的数据读/写到非易失性RAM(NVRAM).我想避免为每个值编写单独的读/写函数来存储在NVRAM中,如下所示:

void Write_Value1(int value);
int Read_Value1(void);
void Write_Value2(unsigned long value);
unsigned long Read_Value2(void);
...
Run Code Online (Sandbox Code Playgroud)

随着读/写项目列表的增长,维护起来非常麻烦.有几种方法可以用C++解决这个问题,例如模板.使用模板我可以写一个.Read().Write(T value)功能的每个项目进行读/写将有机会获得.无论如何从C获得这种行为?我怀疑有一些方法,使用void指针和vtable的一些组合.我想以更多态的方式处理这个问题,并且具有以类似的方式读取/写入每个项目到NVRAM的功能.

AnT*_*AnT 10

您可以[非常接近]通过使用宏来模拟C中的C++模板.

至少有两种方法可以做到这一点.


第一种方法:"橡皮图章"宏

为您的函数定义声明/定义宏

#define DECLARE_READ_WRITE(suffix, type)\
  type Read_Value_##suffix(void);
  void Write_Value_##suffix(type val);

#define DEFINE_READ_WRITE(suffix, type)\
  type Read_Value_##suffix(void) {\
    /* your code */ \
  }\
  void Write_Value_##suffix(type val) {\
    /* your code */ \
  }
Run Code Online (Sandbox Code Playgroud)

然后在一些头文件中做

DECLARE_READ_WRITE(long, long)
DECLARE_READ_WRITE(int, int)
Run Code Online (Sandbox Code Playgroud)

并在一些实现文件中

DEFINE_READ_WRITE(long, long)
DEFINE_READ_WRITE(int, int)
Run Code Online (Sandbox Code Playgroud)

这将"生成"的声明和定义Read_Value_int,Write_Value_int, Read_value_longWrite_value_long.


第二种方法:参数化包含文件

创建两个头文件.一个用于声明(read_write.h.template)

TYPE__ CONCAT(Read_Value_, SUFFIX__)(void);
void CONCAT(Write_Value_, SUFFIX__)(TYPE__ val);
Run Code Online (Sandbox Code Playgroud)

和一个定义(read_write.c.template)

TYPE__ CONCAT(Read_Value_, SUFFIX__)(void)
{
  /* your code */
}

void CONCAT(Write_Value_, SUFFIX__)(TYPE__ val)
{
  /* your code */
}
Run Code Online (Sandbox Code Playgroud)

CONCAT是宏标记连接的通常实现(也可以/应该在第一个方法中使用).

然后将您的"模板化"代码包含到适当的头文件和实现文件中

#define TYPE__ int
#define SUFFIX__ int
#include "read_write.h.template"
#undef TYPE__
#undef SUFFIX__

#define TYPE__ long
#define SUFFIX__ long
#include "read_write.h.template"
#undef TYPE__
#undef SUFFIX__
Run Code Online (Sandbox Code Playgroud)

带头的一些实现文件中的相同内容read_write.c.template.

后一种方法具有产生可调试代码的额外好处.也就是说,你可以在调试器中单步执行它,就像它通常适用于C++模板一样.