C-функция внутри структуры
Я пытаюсь создать функцию внутри структуры, пока у меня есть этот код:
typedef struct client_t client_t, *pno;
struct client_t
{
pid_t pid;
char password[TAM_MAX]; // -> 50 chars
pno next;
pno AddClient()
{
/* code */
}
};
int main()
{
client_t client;
//code ..
client.AddClient();
}
:клиент.h: 24: 2: ошибка: ожидается‘:’, ‘,’, ‘;’, ‘}’ или'атрибут ‘ before ’ {'token.
Как правильно это сделать ?
5 ответов:
это не может быть сделано напрямую, но вы можете эмулировать то же самое, используя указатели функций и явно передавая параметр "this":
typedef struct client_t client_t, *pno; struct client_t { pid_t pid; char password[TAM_MAX]; // -> 50 chars pno next; pno (*AddClient)(client_t *); }; pno client_t_AddClient(client_t *self) { /* code */ } int main() { client_t client; client.AddClient = client_t_AddClient; // probably really done in some init fn //code .. client.AddClient(&client); }
оказывается, что делать это, однако, на самом деле не купить вам очень много. Таким образом, вы не увидите много API-интерфейсов C, реализованных в этом стиле, так как вы можете просто вызвать свою внешнюю функцию и передать экземпляр.
как отмечали другие, встраивание указателей функций непосредственно в вашу структуру обычно зарезервировано для специальных целей, таких как функция обратного вызова.
то, что вы, вероятно, хотите, это что-то вроде таблицы виртуальных методов.
typedef struct client_ops_t client_ops_t; typedef struct client_t client_t, *pno; struct client_t { /* ... */ client_ops_t *ops; }; struct client_ops_t { pno (*AddClient)(client_t *); pno (*RemoveClient)(client_t *); }; pno AddClient (client_t *client) { return client->ops->AddClient(client); } pno RemoveClient (client_t *client) { return client->ops->RemoveClient(client); }
Теперь добавление дополнительных операций не изменяет размер
client_t
структура. Теперь такая гибкость полезна только в том случае, если вам нужно определить много видов клиентов или хотите разрешить пользователям вашегоclient_t
интерфейс возможность увеличить, как ведут себя операции.такая структура появляется в реальном коде. Уровень OpenSSL BIO выглядит примерно так же, а также интерфейсы драйверов устройств UNIX имеют такой же уровень.
Это будет работать только в C++. Функции в структурах не являются особенностью C.
то же самое касается вашего клиента.AddClient(); вызов ... это вызов функции-члена, которая является объектно-ориентированным программированием, т. е. C++.
преобразуйте свой источник в a .cpp файл и убедитесь, что вы компилируете соответственно.
Если вам нужно придерживаться C, код ниже (вроде) эквивалентен:
typedef struct client_t client_t, *pno; struct client_t { pid_t pid; char password[TAM_MAX]; // -> 50 chars pno next; }; pno AddClient(pno *pclient) { /* code */ } int main() { client_t client; //code .. AddClient(client); }
Как насчет этого?
#include <stdio.h> typedef struct hello { int (*someFunction)(); } hello; int foo() { return 0; } hello Hello() { struct hello aHello; aHello.someFunction = &foo; return aHello; } int main() { struct hello aHello = Hello(); printf("Print hello: %d\n", aHello.someFunction()); return 0; }
вы пытаетесь сгруппировать код в соответствии со структурой. Группы с помощью файла. Вы помещаете все функции и внутренние переменные в заголовок или заголовок и объект ".o файл", составленный из исходного файла c.
не стоит изобретать объектную ориентацию с нуля для программы на C, которая не является объектно-ориентированным языком.
Я видел это раньше. Это очень странная вещь. Кодеры, некоторые из них, имеют отвращение к передаче объекта, который они хотят изменить в функцию, чтобы изменить его, Хотя это стандартный способ сделать это.
Я виню C++, потому что он скрыл тот факт, что объект класса всегда является первым параметром в функции-члене, но он скрыт. Таким образом, похоже, что он не передает объект в функцию, даже если это так.
Client.addClient(Client& c); // addClient first parameter is actually // "this", a pointer to the Client object.
C гибко и может принять проходить вещи ссылкой.
функция C часто возвращает только байт состояния или int, и это часто игнорируется. В если правильная форма может быть
err = addClient( container_t cnt, client_t c); if ( err != 0 ) { fprintf(stderr, "could not add client (%d) \n", err );
addClient будет в клиенте.h или клиент.c