Как запрограммировать концепции высокого уровня (например, объектный класс и Generics) в C - PullRequest
1 голос
/ 12 октября 2010

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

Есть ли у кого-нибудь полезные советы о том, как в C (или на Ассемблере) программировать концепцию Object Class и / или концепцию Generics на язык. (ссылаясь на реализации Java Object и Generics)

Например, в Java все классы расширяют Object. Итак, как вы представляете это на уровне C? это что-то вроде:

#include <stdio.h>

typedef struct {
  int stuff;
} Object;


typedef struct {
  int stuff;
  Object object;
} ChildClass;


int main() {
    ChildClass childClass;
    childClass.stuff = 100;
    childClass.object.stuff = 200;
    printf("%d\n", childClass.stuff);
    printf("%d\n", childClass.object.stuff);
}

И я даже не совсем уверен, как начать реализацию чего-то вроде Generics. Я также ценю любые ценные ссылки, касающиеся дизайна языка программирования. Спасибо,

Ответы [ 5 ]

5 голосов
/ 12 октября 2010

Взгляните на Структура и интерпретация компьютерных программ Абельсона и Суссмана.Хотя он не показывает, как это сделать в C, он демонстрирует, как создавать типы во время выполнения и как создавать объектную систему поверх языка, который не обеспечивает встроенную поддержку.Как только вы поймете основные идеи, вы сможете использовать структуры и указатели функций для создания реализации.Конечно, изучение исходного кода препроцессора C ++ также будет поучительным.Одно время C ++ был просто препроцессором для компилятора Си.

3 голосов
/ 12 октября 2010

Некоторое время назад я нашел эту книгу, интересную для чтения: Объектно-ориентированное программирование с ANSI-C (PDF).

В C я создал классоподобные структуры и методы, используя struct s (для хранения состояния класса) и функции, которые на них указывают (методы класса).Реализация таких вещей, как наследование, возможна, но быстро запутается.Хотя я не Java-парень, и я не уверен, какую часть Java вы должны нажимать на C, это очень разные языки.;Я написал его для одновременного запуска нескольких ПИД-регуляторов.

//! PID control system state variables
typedef struct {
    const PID_K * K;  //!< PID control parameters
    int32_t e; //!< Previous error (for derivative term)
    int32_t i; //!< Integrator
} PID_SYS;

void PID_Init(PID_SYS * sys, const PID_K * K)
{
    sys->i = 0;
    sys->e = 0;
    sys->K = K;
}

int16_t PID_Step(PID_SYS * sys, int32_t e)
{
    // ...PID math using "sys->" for any persistent state variables...
}
2 голосов
/ 13 октября 2010

Если ваша цель - написать новый язык, который включает в себя концепции высокого уровня, возможно, вы захотите взглянуть на источники CPython.CPython - это объектно-ориентированный язык программирования, интерпретатор которого написан на языке C. Также существуют реализации компиляторов / интерпретаторов для C ++, D, Javascript, Go, Objective C и многих других программ с открытым исходным кодом.

1 голос
/ 13 октября 2010

Это определенно не С, но я бы посоветовал взглянуть на Луа.

По своей сути, Lua имеет только несколько основных типов: число, строка, логическое значение, функция и таблица (хотя есть еще пара вопросов, выходящих за рамки этой темы. Таблица по сути является просто хеш-таблицей, которая принимает ключи любого типа и может содержать значения любого типа.

Вы можете реализовать ООП в Lua с помощью metatables . В Lua для таблицы разрешено иметь до одной метатабельной таблицы, к которой обращаются при особых обстоятельствах , например, когда таблица добавляется или умножается на другую таблицу или когда вы пытаетесь получить доступ к ключу, который присутствует в таблице.

Используя метатаблицы, вы можете быстро и легко достичь чего-то совершенно похожего на наследование, объединив несколько метатаблиц. Когда вы пытаетесь получить доступ к отсутствующему ключу в таблице, Lua ищет ключ с именем __index в метатабельной таблице. Поэтому, если вы попытаетесь получить доступ к ключу с именем foo в таблице, у которой такого ключа нет, Lua проверит наличие foo в первой метатаблице. Если его там нет и метатабель имеет собственный метатабл с определенным __index, он проверит наличие foo в следующем и т. Д.

Как только вы поймете, как просто сделать это в Lua, перевод на C становится очень достижимым. Конечно, ваш ООП будет полностью во время выполнения, но он действительно будет очень похож на ООП.

1 голос
/ 12 октября 2010

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

См. gobject .

...