C函数装饰/多态

时间:2011-05-04 20:51:07

标签: c pointers polymorphism decorator abstraction

我是否可以通过某种方式在基本函数中为所有操作类型执行代码?我想执行所有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);

4 个答案:

答案 0 :(得分:3)

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

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);

肯定是我的C生锈的错误,但这就是我认为的主旨。

答案 1 :(得分:2)

有没有什么能阻止你简单地创建像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);
}

答案 2 :(得分:2)

如果确实想要模仿多态,那么,它就会变得丑陋。

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 ++。

答案 3 :(得分:0)

如果我正确理解了这个问题,你能不能简单地创建一个具有一定属性的公共打印功能,并从每个do_cardX函数调用该公共打印功能?

C中没有模板,所以你不能创建一个通用的单do_card()函数来在函数调用点实例化它的参数类型,即使你可以,你仍然需要创建某种类型的专用打印功能,每个功能必须调用这些功能,以便从每种特定类型的do_card()功能打印您想要的特定游戏状态信息。