C 结构函数指针传递自引用作为参数

问题描述 投票:0回答:3

我想运行具有自动填充功能的结构指向的函数。

这是我正在研究的部分:

#include <stdio.h>
#include <stdlib.h>

struct Fra { //Fraction
  int n;     //Numerator
  int d;     //Denominator
  void (*p)(struct Fra*);
  void (*sD)(int, struct Fra*);
  void (*sN)(int, struct Fra*);
};

void print(struct Fra*);
void setDenom(int, struct Fra*);
void setNum(int, struct Fra*);

int main() {

  struct Fra* fraA = 0;

  fraA = (struct Fra*) malloc(sizeof(struct Fra));

  fraA->sN = setNum;
  fraA->sN(2, fraA);
  fraA->sD = setDenom;
  fraA->sD(3, fraA);
  fraA->p = print;
  fraA->p(fraA);

  return 0;
}

这就是我一直在努力实现的目标

来自:

fraA->sN(2, fraA);
fraA->sD(3, fraA);
fraA->p(fraA);

致:

fraA->sN(2);
fraA->sD(3);
fraA->p();

经过一段时间的试错后,我得出的结论是我需要这方面的帮助。我尝试过浏览,但似乎没有正确的关键字,所以我无法验证这个问题是否是双重的。

感谢您的帮助。

c struct arguments function-pointers self-reference
3个回答
2
投票

您可以声明一些宏来始终传递正确的引用,这就是您所能做的:

#define FRA_NEW(this, sN sD, sP) \
{ \
  (this) = calloc(sizeof(*(this))) \
  if (this) \
  { \
    (this)->sN = (sN); \
    (this)->sN = (sD); \
    (this)->sN = (sP); \
  } \
}

#define FR_DELETE(this) \
  free(this)

#define FRA_PRINT(this) \
  (this)->print(this)

#define FRA_SETNUM(this, num) \
  (this)->setNum(this, num)

#define FRA_SETDENOM(this, denom) \
  (this)->setDenom(this, denom)

我还建议将“this”始终作为“成员”函数的第一个参数。

int main(void) 
{
  struct Fra * fraA = NULL;

  FRA_NEW(fraA, setNum, setDenom, print);
  if (NULL == fraA)
  {
    perror("FRA_NEW() failed");
    return 1;
  }

  FRA_SETNUM(fraA, 2);
  FRA_SETDENOM(fraA, 3);
  FRA_PRINT(fraA);

  FRA_DELETE(fraA);

  return 0;
}

1
投票

我能想到的唯一真正有用的方法是提供完成这项工作的函数:

void call_print(struct Fra* fra)
{
    fra->p(fra);
}

void call_setDenom(int val, struct Fra* fra)
{
    fra->sD(val, fra);
}

void call_setNum(int val, struct Fra* fra);
{
    fra->sN(val, fra);
}

并使用这些:

call_setNum(2, fraA);
call_setDenom(3, fraA);
call_print(fraA);

0
投票

有一个对我有用的例子:

typedef struct _log_t
{
    log_level_t threshold;
    void (*logger)(struct _log_t*, log_level_t, char *, ...);
} 
log_t;
© www.soinside.com 2019 - 2024. All rights reserved.