как реализовать класс в C [дубликат]

Возможный дубликат:

Как вы реализуете класс в C?

В моем тесте мне сказали, что мне нужно найти способ реализовать следующий класс в C

class A
{
    private:
      int a,b;
    public:
      void func1();
      int c,d;
    protected:
      int e,f;
      void fun();
};

Также компилятор C поддерживает спецификаторы доступа private, public и protected внутри структур?

 Mike23 окт. 2012 г., 16:04
Ищите так, прежде чем отправлять:Реализуйте класс в C
 Gorpik23 окт. 2012 г., 15:55
Первоначально C ++ называлсяC с классами ", Была причина для этого :)
 auselen23 окт. 2012 г., 15:54
домашнее задание? мы небольше не делаю домашних заданий.

Ответы на вопрос(8)

а C ++ ...

 texasbruce23 окт. 2012 г., 15:56
И тогда вам придется каждый раз назначать каждый указатель функции на экземпляр
 harper23 окт. 2012 г., 15:57
Ты нене нужен указатель в "учебный класс" пример. Дон»Добавить указатель на структуру, если вы не хотите имитировать виртуальные функции. И даже в этом случае у вас нет указателя на функции в структуре, но есть указатель на таблицу функций.

ть некоторые функции функций-членов класса С ++ с помощью бесплатных функций:

struct A { int a, b, c, d, e, f; };

void A_func1(struct A * th) { /* use "th->a" etc. */ }
void A_fun(struct A * th) { /* ditto */ }

Использование:

struct A a;

A_func1(&a);
A_fun(&a);

Как говорит @CashCow, вы можете получить приличное разделение реализации и интерфейса, правильно структурировав свои единицы перевода. Например:

mylib.h: (отправить это)

struct A;
void A_func1(struct A *);

mylib_secret_impl.c: (только грузим бинарный файл!)

#include "mylib.h"

struct A { int a, b, c, d, e, f; };

void A_fun(struct A * th) { /* ... */ }
void A_func1(struct A * th) { /* use A_fun(th) and members of *th */ }
 Mike23 окт. 2012 г., 16:07
@Lundin - Где в этом посте у вас есть "частный" данные?
 Kerrek SB23 окт. 2012 г., 16:04
@Lundin: Этоне контроль доступа, и этоЭто не языковая особенность. Это'Это просто техника программирования. К тому же, вы могли бы сказать, что "C имеет TCP / IP "просто потому чтоМожно написать библиотеку TCP / IP на языке C. Или полиморфизм или наследование в этом отношении. Вы всегда можетедобиться эффекта (потому что вы можете сделать что-нибудь в C), но этоне родной язык
 Lundin23 окт. 2012 г., 16:25
@KerrekSB Вы не правы, неполный тип является языковой особенностью языка C. См. C11 6.7.2.3.
 Kerrek SB23 окт. 2012 г., 16:32
@Lundin: неполные типы также существуют в C ++. Но в C ++ есть контроль доступа.
 Lundin23 окт. 2012 г., 16:00
-1 для неправильного утверждения об отсутствии контроля доступа в C. Смотрите ссылку, которую я разместил, чтобы увидеть, как достигается частная инкапсуляция в C.
 Lundin23 окт. 2012 г., 16:36
@KerrekSB Да, C ++ обеспечивает частную инкапсуляцию менее уродливыми способами. Но это неЭто означает, что вы не можете достичь этого в C с помощью языковой функции, известной как неполный тип.
 Lundin23 окт. 2012 г., 16:29
@Mike Обновлено. Структура в файле C имеет реализацию, которая не видна или недоступна вызывающей стороне. Концепция известна как непрозрачный / неполный тип.

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

/* Foo.h */
struct Foo {
    int c, d;
};

struct Foo* newFoo(); /* you can't create these on the stack */
void Foo_func1(struct Foo*);

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

/* Foo.c */
struct Foo_private {
    struct Foo pub;
    int a, b;
    int e, f; /* note I'm not distinguishing private */
};

struct Foo* newFoo()
{
    struct Foo_private *f = malloc(sizeof(*f))
    /* initialize */
    return &f->pub;
}

struct Foo_private* cast(Foo *f)
{
    /* can do cunning things with offsets for inheritance,
       but this is the easy case */
    return (Foo_private *)f;
}

void Foo_func1(Foo *f)
{
    struct Foo_private *fp = cast(f);
    /* access private members here */
}
 Useless23 окт. 2012 г., 16:35
Кто сказал что-нибудь о чистом ОО-дизайне? OP»S вопрос имеет публичных членов, я дал публичных членов.
 Lundin23 окт. 2012 г., 16:37
Да я знаюЯ просто указываю на то, что первоначальный вопрос изначально был некорректным.
 Lundin23 окт. 2012 г., 16:34
В чистом ОО-дизайне нет никакой причины иметь открытые переменные-члены. Это неЭто не имеет смысла и в C ++.

Можно реализовать некоторые функции проектирования ОО в C с помощью указателей и PIMPL.

Вот как я мог бы реализовать класс в C:

хиджры

   struct privateA;
   struct A {
     struct A_private* private;
     int c,d;
   };
   extern void A_func1(struct A*);
   extern struct A* A_new();

A.c

   struct A_private {
     int a,b;
     int e,f;
   };

   static struct A_private* A_private_new() {
     struct A_private_new* this = malloc(sizeof(struct A_private);
     this->a = 0;
     this->b = 0;
     this->e = 0;
     this->f = 0;
   }

   struct A* A_new() {
     struct A* this = malloc(sizeof (struct A));
     this->private = A_private_new();
     this->c = 0;
     this->d = 0;
   }

   void A_func1(struct A* this) { this->c = 12; }
   static void A_fun(struct A* this) { this->d = 7; }  

main.c:

#include "A.h"
int main () {
  struct A* a = A_new();
  A_func1(a);
}
 Lundin23 окт. 2012 г., 16:23
Однако в C и C ++ нет никакой причины иметь открытые переменные-члены, поскольку все должно быть доступно через setter / getters в чистом OO-дизайне. Если вы удалите общедоступные переменные-члены, вы можете удалить всю декларацию структуры в заголовочном файле, и код станет легче для понимания и поддержки.

прозрачный тип, или, более формально, неполный тип.

myclass.h

typedef struct myclass myclass;


myclass* myclass_construct (void);

void     myclass_set_x (myclass* this, int x);
int      myclass_get_x (const myclass* this);

void     myclass_destruct (myclass* this);

myclass.c

#include "myclass.h"

struct myclass
{
    int x; // this is a private variable
};


myclass* myclass_construct (void)
{
    myclass* instance = malloc (sizeof(myclass));

    if(instance == NULL) { /* error handling */ }

    instance->x = 0;

    return instance; 
}

void myclass_set_x (myclass* this, int x)
{
    this->x = x;
}

int myclass_get_x (const myclass* this)
{
    return this->x;
}

void myclass_destruct (myclass* this)
{
    free(this);
}

static myclass_private_member (something_t s)
{
    // pure private function, do something internal here
}

main.c

#include "myclass.h"

myclass* mc = myclass_construct();
...

Также нет:private

struct A
{
   int a, b;
   int c, d;
   int e, f;
};

void func1( struct A* );

void fun( struct A* );

Но все публично.

Чтобы сделать вещи более инкапсулированными, вы должны скрыть фактические детали реализации структуры A и показать только предварительное объявление с открытыми методами.

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

В вашем классе вы сделали двух участников публичными, но если мыскрывать" структура А мы все скрываем, поэтому вместо них предоставляем геттеры и сеттеры.

В качестве альтернативы мы можемскрывать" часть нашей структуры, что-то вроде: struct A1;

struct A
{
   struct A1 * privatePart;
   int b, c;  // public part     
};

хотя получитсябеспорядочный" как вы должны начать выделять приватную часть (и помните, что в C нет умных указателей или деструкторов, так что вы 'Я должен быть намного осторожнее с управлением памятью).

Для этого многие API-интерфейсы C используют соглашение об именах, согласно которому они называют "частный" переменные "зарезервированный", часто защищены1, защищены2 и т. д. Компилятор победил 'не переставайте писать им, но вы, очевидно, делаете это на свой страх и риск, и очевидно, что вы не должны иметь доступ к этим членам (кроме прямого копирования или аналогичного).

 infect23 окт. 2012 г., 15:55
Да. Но это был один из вопросов в моем тесте, и мне нужно преобразовать его в C, используя любую конструкцию, которую я хочу.
 CashCow23 окт. 2012 г., 16:35
Да, область видимости файла - это один из способов определения области видимости, другой - это область видимости библиотеки, где функция не экспортируется, поэтому те, кто использует библиотеку, выиграютне сможет увидеть или вызвать метод. Это то, что я имел в виду, говоря о дружбе.
 user150004923 окт. 2012 г., 16:06
статическая функция в c может быть вызвана только в этом конкретном файле c. так что вроде как приват, если вы рассматриваете этот файл c как область видимости класса.

но с помощью struct и функций вы можете выполнять базовый процесс без наследования и полиморфизма.

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

// foo.h
typedef struct Foo Foo;
Foo * FooAlloc(int bar);
void  FooFree(Foo *);

// foo.c
struct Foo {
    int bar;
};
Foo * FooAlloc(int bar){
    Foo * f = malloc(sizeof(*f));
    f->bar = bar;
    return f;
}
void FooFree(Foo * f){free(f);}

bar Доступ к элементу структуры Foo возможен только из функций в foo.c. Недостатком является то, что вы можетесоздать Foo в стеке. Точно так же вы можете поместить определение в отдельныйfoo_private.h» заголовок для эмуляции защищенного доступа.

 Lundin23 окт. 2012 г., 16:18
Черт, ты меня побил :)оставлю мой ответ таким, какой он есть, и проголосую за это.

Ваш ответ на вопрос