Как определить конструктор в C - PullRequest
0 голосов
/ 01 июня 2011

Как можно создать конструктор в стиле Haskell / C ++ в C? Кроме того, если у меня есть этот новый объект, как я могу определить в нем операции (такие как LinkedList / Tree)?

Ответы [ 2 ]

17 голосов
/ 01 июня 2011

C не имеет языковой поддержки для объектно-ориентированных концепций, таких как конструкторы.

Вы могли бы реализовать это вручную в соответствии с:

typedef struct
{
    int field1;
    int field2;
} MyObject;

MyObject *MyObject_new(int field1, int field2)
{
    MyObject *p = malloc(sizeof(*p));
    if (p != NULL)
    {
        // "Initialise" fields
        p->field1 = field1;
        p->field2 = field2;
    }
    return p;
}

void MyObject_delete(MyObject *p)
{
    // Free other resources here too
    if (p != NULL)
    {
        free(p);
    }
}

void MyObject_doSomethingInteresting(const MyObject *p)
{
    printf("How interesting: %d\n", p->field1 * p->field2);
}

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

См. Также этот вопрос .

См. Также этот ответ на часто задаваемые вопросы , если вы заинтересованы в компиляции объектно-ориентированного C ++ в C.

4 голосов
/ 01 июня 2011

Я подозреваю, что ответ @Oli Charlesworth - это то, что вы действительно хотели здесь, но ради полноты, если вы действительно хотите конструкторы в стиле Haskell :

  • Нулевые конструкторы данных, такие как True и False, могут быть легко представлены обычными типами enum. Чтобы быть точным по отношению к Haskell, вам нужно делать вид, что вы не можете рассматривать их как целочисленные значения, если только вы не притворяетесь, что ваш тип Haskell является экземпляром Enum.

  • Конструкторы данных для типов продуктов, таких как (True, "abc"), могут быть представлены функциями, которые принимают соответствующие аргументы и возвращают соответствующий struct. «Синтаксис записей» в Haskell можно имитировать с помощью struct, поскольку структуры в стиле C уже имитируются синтаксисом записей Haskell. Уу, рекурсия!

  • Конструкторы данных для типов сумм, таких как Nothing и Just 5, можно имитировать с помощью union. Чтобы быть точным в отношении Haskell, вам нужно «пометить» объединение, чтобы безопасно различать регистры, например, используя struct и enum. Представьте, что | в объявлениях данных на Haskell указывает на нетегированное объединение, а отдельные конструкторы, такие как Nothing и Just, являются нулевыми конструкторами, которые должны быть первым элементом типа продукта, формирующего каждую ветвь. Это немного сложнее в реализации, чем вы могли подумать, поняв, что это проще, чем кажется на первый взгляд.

  • Конструкторы типов на самом деле не очень хорошо переводятся в C. Возможно, вы сможете плохо имитировать, если хотите, используя макросы и тому подобное. Но вы, вероятно, не хотите, поэтому придерживайтесь мономорфного кода.

Если вы хотите применить что-либо из вышеперечисленного на практике в реальном коде, хорошо ... удачи и бога.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...