Функции в структуре - PullRequest
       10

Функции в структуре

28 голосов
/ 19 ноября 2010

Могут ли структуры содержать функции?

Ответы [ 7 ]

35 голосов
/ 19 ноября 2010

Нет, но они могут содержать указатели на функцию .

Если вы намереваетесь сделать некоторую форму полиморфизма в C, тогда да, это можно сделать:

typedef struct {
    int (*open)(void *self, char *fspec);
    int (*close)(void *self);
    int (*read)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
    int (*write)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
    // And data goes here.
} tCommClass;

Выше typedef была структура, которую я создал для библиотеки связи общего назначения.Чтобы инициализировать переменную, вы должны:

tCommClass *makeCommTcp (void) {
    tCommClass *comm = malloc (sizeof (tCommClass));
    if (comm != NULL) {
        comm->open  = &tcpOpen;
        comm->close = &tcpOpen;
        comm->read  = &tcpOpen;
        comm->write = &tcpWrite;
    }
    return comm;
}

tCommClass *makeCommSna (void) {
    tCommClass *comm = malloc (sizeof (tCommClass));
    if (comm != NULL) {
        comm->open  = &snaOpen;
        comm->close = &snaOpen;
        comm->read  = &snaOpen;
        comm->write = &snaWrite;
    }
    return comm;
}

tCommClass *commTcp = makeCommTcp();
tCommClass *commSna = makeCommSna();

Затем вызвать функции, например:

// Pass commTcp as first params so we have a self/this variable
//   for accessing other functions and data area of object.
int stat = (commTcp->open)(commTcp, "bigiron.box.com:5000");

Таким образом, для TCP можно использовать один тип, SNA, RS232 или даже опорные несущие, с точно таким же интерфейсом.

5 голосов
/ 19 ноября 2010

edit Устранить неоднозначность с использованием «типов данных»

Не в C. struct типы могут содержать только данные.

Из раздела 6.7.2.1 стандарта ISO C99.

Структура или объединение не должны содержать элемент с неполным или функциональным типом (следовательно, структура не должна содержать свой экземпляр, номожет содержать указатель на сам экземпляр), за исключением того, что последний член структуры с более чем одним именованным членом может иметь неполный тип массива;такая структура (и любое объединение, содержащее, возможно, рекурсивно член, являющийся такой структурой) не должно быть членом структуры или элементом массива.

0 голосов
/ 18 сентября 2017

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

#include<iostream>
#include<cstring>
using namespace std;

struct full_name
{
  char *fname;
  char *lname;
  void (*show)(char *,char*);
};

void show(char *a1,char * a2)
{
  cout<<a1<<"-"<<a2<<endl;
}

int main()
{  
  struct full_name loki;
  loki.fname="Mohit";
  loki.lname="Dabas";
  loki.show=show;
  loki.show(loki.fname,loki.lname);

  return 0;     
}
0 голосов
/ 23 июня 2017

Они могут, но в обычном программировании на Си нет никаких преимуществ.

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

Стандартной организационной структурой C является Файл, с интерфейсы в заголовке и реализации в источнике.

Так работает libc и так работают почти все библиотеки C.

Компиляторы Moder C позволяют определять и реализовывать функции в одном и том же исходном файле и даже реализовывать статические функции в заголовочных файлах. Это, к сожалению, приводит к некоторой путанице относительно того, что и куда идет, и вы можете получить необычные решения, такие как скручивание функций в структуры, программы только для исходного кода без заголовков и т.д. Таким образом вы теряете преимущество отделения интерфейса от реализации.

0 голосов
/ 19 ноября 2010

Да, возможно объявить функцию, и определение функции не допускается, и это должен быть указатель на функцию.

Он основан на теговой структуре C99.

Локеш В

0 голосов
/ 19 ноября 2010

Все в порядке. В коде ядра Linux вы найдете много структур, содержащих функции. такие как:

/*


* The type of device, "struct device" is embedded in. A class
 * or bus can contain devices of different types
 * like "partitions" and "disks", "mouse" and "event".
 * This identifies the device type and carries type-specific
 * information, equivalent to the kobj_type of a kobject.
 * If "name" is specified, the uevent will contain it in
 * the DEVTYPE variable.
 */
struct device_type {
        const char *name;
        struct attribute_group **groups;
        int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
        void (*release)(struct device *dev);
        int (*suspend)(struct device * dev, pm_message_t state);
        int (*resume)(struct device * dev);
};
0 голосов
/ 19 ноября 2010

В C структурам разрешено содержать значения данных, а не указатели функций.Не допускается в C., но следующее работает буквально нормально при проверке с gcc.

enter code here

#include <stdio.h>

struct st_func_ptr{
        int data;
        int (*callback) ();
};

int cb(){
        printf(" Inside the call back \n");
        return 0;
}

int main() {
        struct st_func_ptr sfp = {10, cb};

        printf("return value = %d \n",sfp.callback());

        printf(" Inside main\n");
        return 0;
}

Итак, я в замешательстве ...

...