2013-09-26 4 views
5

Я пытаюсь создать связанный список в C, но пытаясь его легко упаковать в виде класса стиля C++. У меня возникли некоторые проблемы, однако с помощью указателей на функции в C.C: указатель функции внутри структуры typedef

typedef struct linkedList { 
    int count; 
    struct msgNode *front; 
    struct msgNode *back; 
    void (*addMSG)(unsigned char *, int, struct linkedList *); 
} msgList; 

void addMSG(unsigned char *data, int size, struct linkedList *self); 

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

В настоящее время я получаю ошибку сегментации, когда я вызываю addMSG, что из-за того, что addMSG не указывает на функцию. Тем не менее, я не хочу указывать функцию, указывающую на каждый раз, когда я хочу использовать связанный список. Есть ли хороший способ иметь указатели на функции без необходимости указывать на функцию, или вам нужно неявно указывать ее на функцию?

Это только частичная реализация, показанная здесь. В конце эта структура будет иметь все необходимые функции. Это просто для того, чтобы держать этот вопрос коротким и точным.

+2

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

+1

[В предыдущем ответе] (http://stackoverflow.com/a/17622474/315052) я более подробно объясню, как это можно сделать так, чтобы фактически поддерживать динамическую диспетчеризацию. – jxh

ответ

21

Вам необходимо назначить функцию элементу. я также рекомендую давать им разные имена:

typedef void (*addMSGFunc)(unsigned char *, int, struct linkedList *); 

typedef struct linkedList { 
    int count; 
    struct msgNode *front; 
    struct msgNode *back; 
    addMSGFunc addMSG; 
} msgList; 

void addMSGImpl(unsigned char *data, int size, struct linkedList *self) 
{ 
    ... 
} 

И затем после создания msgList:

msgList myList; 
myList.addMSG = addMSGImpl; 
+0

'myList.addMSG = addMSGImpl;' как передать аргументы? – saruftw

+1

@ saru95 Когда вы называете это: 'myList.addMsg (buffer, 20, list)' – Asaf

1

Вы можете иметь неинициализированный указатель на функцию просто отлично до тех пор, пока вы на самом деле не использовать его. Если вы do хотите использовать его для вызова функции, то, очевидно, вам нужно назначить ему функцию. C не может угадать, какую функцию вы хотите использовать.

Если у вас есть структура связанного списка, где иногда вам нужна функция, а иногда нет, то просто назначьте ей NULL при создании списка, и если ваша реализация списка вызывает функцию только тогда, когда она не является NULL ,

Если он всегда указывает на ту же функцию, то просто выполните назначение в своей функции конструктора.

2

Ну вы не можете добавить значение по умолчанию в объявлении структуры, но то, что вы можете сделать, это:

  • Создание функции для инициализации экземпляра linkedList - Я думаю, вы уже видели, что в C style
  • Создайте элемент списка по умолчанию и используйте его при создании новых объектов.

Как:

void addMSG(unsigned char *data, int size, struct linkedList *self); 

struct linkedList { 
    int count; 
    struct msgNode *front; 
    struct msgNode *back; 
    void (*addMSG)(unsigned char *, int, struct linkedList *); 
} DefaultList = {0, NULL, NULL, addMSG}; 
Смежные вопросы