05 February 2014

Classes and objects in C

If, for reasons other than sheer amusement, you need C with classes/objects, you better use C++. This is what C++ is primarily for. However, you can also simulate classes/objects in plain C.

Brief and simple, for that:

  1. You ought to use STRUCT of data;

  2. Inside the STRUCT, declare pointers to functions, which will work as the Objects's METHODS, and assign functions' addresses to those pointers;

  3. In order to keep a reference to the Object's context, add an additional STRUCT's property/field as a pointer to the STRUCT itself ("self" in the code below);

  4. This additional Object's field is to be passed to the METHODS in order to access the STRUCT's members.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>

struct CLASS {
  int field1;
  char *field2;
  struct CLASS *self; // pointer to itself
  void (*method1)(struct CLASS *sf); // method 1
  int (*method2)(struct CLASS *sf, int del); // method 2
};

void METH1(struct CLASS *sf) {
    printf("Obj: %d %s\n", sf->field1, sf->field2);
}

int METH2(struct CLASS *sf, int par) {
    return sf->field1 * par;
}

int main(void) {

  /* --- init the object --- */
  struct CLASS obj = { 204, "A string field.", &obj, &METH1, &METH2 };
  
  /* --- prints obj's fields --- */
  obj.method1(obj.self);

  /* --- uses obj's method2 --- */
  printf("Field1: %d, Field2: %s, Method2 returns: %d\n",
        obj.field1, obj.field2, obj.method2(obj.self, 100));

  return 0;
}

That's it. Of course, no constructors or distructor, no private or protected, no inheritance and suchlike, only basic functionality. This is how the above code would look in C++:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>

class CLASS {
    public:
      int field1;
      char *field2;
      void method1(); // method 1
      int method2(int del); // method 2
};

void CLASS::method1() {
    printf("Obj: %d %s\n", field1, field2);
}

int CLASS::method2(int par) {
    return field1 * par;
}

int main(void) {

  /* --- init the object --- */
  CLASS obj = { 204, (char*)"A string field." };
  
  /* --- prints obj's fields --- */
  obj.method1();

  /* --- uses obj's method2 --- */
  printf("Field1: %d, Field2: %s, Method2 returns: %d\n",
        obj.field1, obj.field2, obj.method2(100));

  return 0;
}

No comments:

Post a Comment