C 函数修饰/多态

发布于 2024-11-04 23:42:38 字数 719 浏览 0 评论 0原文

有什么方法可以在所有操作类型的基本函数中执行代码吗?我想执行所有 do_card 操作通用的行为。换句话说,我想打印游戏状态,但我想避免在每个单独的 do_card 函数中重复 printf,而是只写一次。有没有办法在C中实现这个?

struct CARD {
    int value;
    int cost;
    // This is a pointer to a function that carries out actions unique
    // to this card
    int (*do_actions) (struct GAME_STATE *state, int choice1, int choice2);
};
int do_card0(struct GAME_STATE *state, int choice1, int choice2)
{
    // Operate on state here
}

int do_card1(struct GAME_STATE *state, int choice1, int choice2)
{
    // Operate on state here
}

static struct cardDefinitions[] = {
    {0, 1, do_card0},
    {1, 3, do_card1}
};
int result = cardDefinitions[cardNumber].do_action(state, choice1, choice2);

Is there some way I can execute code in the base function for all action types? I want to execute behavior common to all do_card actions. In another words, I want to print the game state, but I want to avoid duplicating a printf in every individual do_card function, and instead write it once. Is there a way to implement this in C?

struct CARD {
    int value;
    int cost;
    // This is a pointer to a function that carries out actions unique
    // to this card
    int (*do_actions) (struct GAME_STATE *state, int choice1, int choice2);
};
int do_card0(struct GAME_STATE *state, int choice1, int choice2)
{
    // Operate on state here
}

int do_card1(struct GAME_STATE *state, int choice1, int choice2)
{
    // Operate on state here
}

static struct cardDefinitions[] = {
    {0, 1, do_card0},
    {1, 3, do_card1}
};
int result = cardDefinitions[cardNumber].do_action(state, choice1, choice2);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南烟 2024-11-11 23:42:39

如果你真的想要模拟多态性,你可以,但它只会变得丑陋。

typedef struct Card_t Card;
typedef struct 
{
   void (*print)(Card*);
   int (*do_action)(Card*, struct GameState*, int);
   /* other possibly card-specific functions here */
} CardMethods;

struct Card_t
{ 
  int value;
  int cost;
  CardMethods* vtab;
};

int stdAct(Card* this, GameState* st, int choice)
{
    this->vtab->print(this);  //do this card's specific print function.
    /* do common actions based on state&choice */
}

int specialPrint1(Card* this)
{
   stdPrint(this); //call parent print function
   printf("something special here");  //add behavior
}

CardMethods standardCard={stdPrint, stdAct};
CardMethods specialCard1={specialPrint1, stdAct};
CardMethods specialCard2={stdPrint, specialAct1};
CardMethods specialCard3={specialPrint2, specialAct2};
static struct cardDefinitions[] = {
 {0, 1, &standardCard},    
 {1, 3, &standardCard}, 
 {2, 3, &specialCard1},
 {2, 4, &specialCard2},
 /*...*/ 
}; 


cardDefinitions[i].vtab->do_action(&cardDefinitions[i], state, choice)

此时,您正在执行 C++ 编译器在幕后执行的大部分操作,您也可以只使用 C++。

If you really want to emulate polymorphism, you can, it just gets ugly.

typedef struct Card_t Card;
typedef struct 
{
   void (*print)(Card*);
   int (*do_action)(Card*, struct GameState*, int);
   /* other possibly card-specific functions here */
} CardMethods;

struct Card_t
{ 
  int value;
  int cost;
  CardMethods* vtab;
};

int stdAct(Card* this, GameState* st, int choice)
{
    this->vtab->print(this);  //do this card's specific print function.
    /* do common actions based on state&choice */
}

int specialPrint1(Card* this)
{
   stdPrint(this); //call parent print function
   printf("something special here");  //add behavior
}

CardMethods standardCard={stdPrint, stdAct};
CardMethods specialCard1={specialPrint1, stdAct};
CardMethods specialCard2={stdPrint, specialAct1};
CardMethods specialCard3={specialPrint2, specialAct2};
static struct cardDefinitions[] = {
 {0, 1, &standardCard},    
 {1, 3, &standardCard}, 
 {2, 3, &specialCard1},
 {2, 4, &specialCard2},
 /*...*/ 
}; 


cardDefinitions[i].vtab->do_action(&cardDefinitions[i], state, choice)

At this point you are doing most of what the C++ compiler does behind the scenes, you may as well just use C++.

哥,最终变帅啦 2024-11-11 23:42:39

是否有什么因素阻止您简单地创建诸如 print_game_state(GAME_STATE *) 之类的子例程并在 do_card 函数中使用它们?

int do_card0(...){
    print_game_state(...);
    //other stuff
}

int do_card0(...){
    print_game_state(...);
    //do different stuff
}

如果这不能解决您的问题,则为类之间不同的每张卡行为创建函数,并使用外部函数中的这些函数。

struct Card{
    int value;
    int cost;
    int (*f1)(struct card* self);
    int (*f2)(struct card* self);
};

void my_function(Card* card){
    card->f1(card);
    printf("something\n");
    card->f2(card);
}

Is there something stoping you from simply creating subroutines like print_game_state(GAME_STATE *) and using them in the do_card functions?

int do_card0(...){
    print_game_state(...);
    //other stuff
}

int do_card0(...){
    print_game_state(...);
    //do different stuff
}

If this doesn't solve your problem, then create functions for each piece of card behaviour that varies between the classes and use these from the outer functions.

struct Card{
    int value;
    int cost;
    int (*f1)(struct card* self);
    int (*f2)(struct card* self);
};

void my_function(Card* card){
    card->f1(card);
    printf("something\n");
    card->f2(card);
}
甜宝宝 2024-11-11 23:42:39

如果我正确理解这个问题,您是否可以简单地创建一个采用一组特定属性的通用打印函数,并从每个 do_cardX 函数调用该通用打印函数?

C 中没有模板,因此您无法创建通用的单个 do_card() 函数来在函数调用时实例化其参数类型,即使可以,您也会仍然创建某种类型的专用打印函数,每个函数都必须调用该函数,以便从每个特定类型的 do_card() 函数打印您想要的特定游戏状态信息。

If I'm understanding this question correctly, can you not simply create a common printing function that takes a certain set of attributes, and call that common print function from each of the do_cardX functions?

There are no templates in C, so you can't create a generic single do_card() function that would instantiate its argument types at the point of the function's call, and even if you could, you would have to still create some type of specialized print function that each function would have to call in order to print the specific game-state information you're wanting from each specific type of do_card() function.

他是夢罘是命 2024-11-11 23:42:38

不要在每张卡上调用 do_action,而是将卡与其他参数一起传递给您定义的另一个函数,让其调用 do 操作方法,然后调用打印状态方法或其他方法,

例如

//add a method like this
int process_card(CARD inCard, GAME_STATE *state, int choice1, int choice2)
{
    inCard.do_action(state, choice1, choice2);
    print_state(state);
}

//last line changes to 
process_card(cardDefinitions[card_number], state, choice1, choice2);

肯定是错误,我的 C 生锈了,但这就是我认为的要点。

rather than calling do_action on each card, pass the card along with the other params to another function you define, have that call the do action method, then call the print state method or whatever

e.g.

//add a method like this
int process_card(CARD inCard, GAME_STATE *state, int choice1, int choice2)
{
    inCard.do_action(state, choice1, choice2);
    print_state(state);
}

//last line changes to 
process_card(cardDefinitions[card_number], state, choice1, choice2);

bound to be errors my C is rusty, but that's the jist I think.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文