2015-10-19 5 views
3

Если я следующая структура определена:Инициализация функции в LL

typedef struct bear_t { 
    char* name; 
    void (*eat)(struct bear_t* this); 
    void (*drink)(struct bear_t* this); 
    void (*sleep)(struct bear_t* this); 
    void (*study)(struct bear_t* this); 
    void (*live)(struct bear_t* this); 
    void (*dtor)(struct bear_t* this); 
    int health; 
    int happiness; 
} bear_t; 

В bear_t * Метод create_bear (аннулируются), я хочу сделать следующее:

  • Создание нового медведя malloc
  • Инициализирует способности медведя есть, пить, спать и жить по умолчанию (eat_fish, drink_water, sleep_lots, live).
  • Инициализирует функцию исследования до NULL, поскольку по умолчанию медведи не знают, как учиться.
  • Инициализирует здоровье и счастье медведя до 0.
  • Инициализирует деструктор медведя (dtor) для удаления_bear.
  • Устанавливает имя медведя на «медведь» (медведь-> имя = «медведь»).
  • Возвращает медведя вызывающему.

Как инициализировать функции?

+0

В C нет прямого пути. Если вы измените эти указатели на функции как статические, вы можете назначить их в самом определении. В противном случае вам нужно создать функцию-оболочку/макрос для создания объекта – knightrider

+0

Это зависит от того, хотите ли вы обнулить любые другие поля или какую другую инициализацию вы планируете делать. – nneonneo

+0

А как насчет других участников? Если установить их все в NULL, это приемлемо, тогда вы можете просто выполнить 'bear_t bear = {0};'. –

ответ

1

Там нет ничего особенно сложного инициализации указателей на функции:

void eat_fish(struct bear_t* this) 
{ 
    this->happiness += 42; 
    this->health += 23; 
} 
void drink_water(struct bear_t* this) 
{ 
    this->happiness += 10; 
    this->health += 12; 
} 
// .... 

bear_t* create_bear(void) 
{ 
    bear_t *bear = (bear_t*)malloc(sizeof(bear_t)); 
    bear->name = "bear"; 
    bear->eat = &eat_fish; 
    bear->drink = &drink_water; 
    bear->sleep = &sleep_lots; 
    bear->live = &live; 
    bear->study = NULL; 
    bear->dtor = &delete_bear; 
    bear->health = 0; 
    bear->happiness = 0; 
    return bear; 
} 

В качестве примечания, пожалуйста, не то, что этот вид объектно-ориентированного кодирования в простом C-стиле действительно не простой способ сделать вещи , Если вы на самом деле пытаетесь попасть на C++ (как предполагают теги к вопросу), попробуйте придерживаться «обычного» способа выполнения таких вещей, которые будут использовать (виртуальные) функции-члены.

+0

OP помечен как C. –

0

Это звучит немного как домашнее задание, но в любом случае, вот один из способов:

bear_t* create_bear(void) 
{ 
    bear_t const default_bear = 
    { 
     .eat = eat_fish; 
     .drink = drink_water; 
     .sleep = sleep_lots; 
     .live = live_the_life; 
     .dtor = delete_bear; 
     .name = "bear"; 
    }; 

    bear_t *new = malloc(sizeof *new); 
    *new = default_bear; 
    return new; 
} 

Любые поля вы не упоминаете в списке инициализатора приготовьтесь к нулю или нулевых указателей.


Вы должны думать немного о char *name, как это не понятно, кто отвечает за распределение памяти для name. Если он предназначен только для строковых литералов, то измените его на char const *name.

Если имя может быть изменено, либо сделайте его массивом, либо укажите его на динамически распределенное пространство (которое delete_bear должно будет знать бесплатно). В последнем случае, возьмите .name из default_bear и добавить строку непосредственно перед return new:

new->name = strdup("bear"); 

(или malloc плюс strcpy, если у вас нет strdup доступны).

Смежные вопросы