【问题标题】:c inherited function extensionc 继承函数扩展
【发布时间】:2021-08-20 18:55:40
【问题描述】:

我在 C 中实现了一些类层次结构:

typedef struct analog_sensor analog_sens;

struct analog_sensor{
        .... /*some  fields*/ 

        void (*fill_output_buf)(analog_sens *, int *);
        
        ..... /*some other fields*/
};

typedef struct {
    analog_sens sensor;
    void (*fill_output_buf)(analog_sens *, int *);
    .../* some other fields */
}ecg_analog_sens ;

我有两个模拟传感器,心电图传感器和声学传感器。它们都填充了输出缓冲区 通过调用以下两个传感器相同的逻辑:

void fill_output_buffer(analog_sens *sensor,
        int *output_length)
{
    ... /* some logic copying filters output to output buffer */
    .... 
    .....
    
}

然后在初始化期间的某个地方我执行以下操作 作业:

    ecg_sens.fill_output_buf = &fill_output_buffer;
    acoustic_sens.fill_output_buf = &fill_output_buffer;

现在 ecg 传感器有更多数据要放入输出缓冲区,我需要使用更多逻辑扩展(覆盖)基本 fill_output_buffer 函数。所以在初始化阶段 心电图实例我执行以下操作:


void ads1299_hog_init(analog_sens *ecg_sens)
{

    /* fill_output_buf function override
    * This is the part I don't like, as I 
    * have to keep pointer to base function
    * on inherited object. It will look 
    * very confusing for someone who will 
    * have to maintain the code in the future
    */ 
    ((ecg_analog_sens* )ecg_sens)->fill_output_buf = ecg_sens->fill_output_buf;
    ecg_sens->fill_output_buf = ads1299_fill_output_buf;
    /* fill_output_buf function override end*/
}

void ads1299_fill_output_buf(analog_sens *sens, int *output_length)
{
    ecg_analog_sens *sensor = (ecg_analog_sens*) sens;
    /* call parrent fill_output_buf */
    /*
    * This is the part I don't like, as I 
    * have to call the base function from 
    * an instance of inherited object. 
    * This might be very confusing for someone 
    * who will have to maintain the code 
    */
    sensor->fill_output_buf(sens, output_length);

    ..../*some additional logic extending the base function */

}


所以当我在 ecg_sens 实例上调用 sensor->fill_output_buf(sensor, &output_length); 时 我实际上是在调用ads1299_fill_output_buf 函数。正如我在上面的 cmets 中所写,我不喜欢从继承对象调用基函数这一事实。这 太混乱了。所以我正在寻找其他一些想法或已知的解决方案。应该是一些新的 可以更好地解决这个问题的关键字。有这个新的 _Generic 关键字,例如,在 C11 中具有函数重载的效果 How to achieve function overloading in C? 但我看不出它对我的情况有何帮助。

谢谢。

【问题讨论】:

  • ecg_analog_sens 中添加一个额外的fill_output_buf 的目的是什么。为什么不使用sensor.fill_output_buf
  • @tstanisl 因为我需要将指向基本函数的指针保存在某个地方,因为我只想按原样使用它,而不是完全覆盖它。实际上,这就是我正在寻找的,以消除这种过度复杂的情况
  • 看起来有点奇怪。你确定analog_sensor::fill_output_buf 应该是多态的吗?也许添加一个普通函数analog_sensor_fill_output_buf(analog_sens*,int*) 来处理analog_sensor 的内容,另外在内部调用fill_output_buf 让派生类调整原始analog_sensor_fill_output_buf()
  • @tstanisl 我在理解 C++ 中的覆盖是如何工作时确实有一个错误,我现在明白了。我将添加问题的更新

标签: c embedded


【解决方案1】:

据我了解,您需要通过sensor.fill_output_buf 指针绕过虚拟调用来调用原始fill_output_buffer。 为什么不从ecg_analog_sens 中去掉fill_output_buf,直接从ads1299_fill_output_buf() 调用fill_output_buffer

typedef struct {
    analog_sens sensor;
    .../* some other fields */
}ecg_analog_sens ;

void ads1299_hog_init(analog_sens *ecg_sens)
{
    ecg_sens->fill_output_buf = ads1299_fill_output_buf;
}

void ads1299_fill_output_buf(analog_sens *sens, int *output_length)
{
    ecg_analog_sens *sensor = (ecg_analog_sens*) sens;
    fill_output_buffer(sens, output_length);
    ..../*some additional logic extending the base function */
}

【讨论】:

  • +1 但我不想直接依赖于继承的类。像这样调用fill_output_buffer 将使我要么在ads1299.c 文件中包含带有fill_output_buffer 原型的标题,要么使extern ... 声明fill_output_buffer
  • @Dabo,您的问题与stackoverflow.com/q/10177809/4989451 非常相似。最赞成的答案与我的相似。最干净的方法是让 ad1299 的 fill_output_buffer 可见
  • 它在 C++ 中是最干净的:Base::fun(); 在 C 中它破坏了 OOD,这是我不想要的。我通过扩展解决了它,从我调用sens->fill_output_buf_extension() 的基本函数开始,我在其中实现了额外的逻辑......
猜你喜欢
  • 2012-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-18
  • 2015-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多