Object-orientation in C

前端 未结 22 1793
孤城傲影
孤城傲影 2020-11-22 15:26

What would be a set of nifty preprocessor hacks (ANSI C89/ISO C90 compatible) which enable some kind of ugly (but usable) object-orientation in C?

I am familiar with

22条回答
  •  天命终不由人
    2020-11-22 16:04

    I'm also working on this based on a macro solution. So it is for the bravest only, I guess ;-) But it is quite nice already, and I'm already working on a few projects on top of it. It works so that you first define a separate header file for each class. Like this:

    #define CLASS Point
    #define BUILD_JSON
    
    #define Point__define                            \
        METHOD(Point,public,int,move_up,(int steps)) \
        METHOD(Point,public,void,draw)               \
                                                     \
        VAR(read,int,x,JSON(json_int))               \
        VAR(read,int,y,JSON(json_int))               \
    

    To implement the class, you create a header file for it and a C file where you implement the methods:

    METHOD(Point,public,void,draw)
    {
        printf("point at %d,%d\n", self->x, self->y);
    }
    

    In the header you created for the class, you include other headers you need and define types etc. related to the class. In both the class header and in the C file you include the class specification file (see the first code example) and an X-macro. These X-macros (1,2,3 etc.) will expand the code to the actual class structs and other declarations.

    To inherit a class, #define SUPER supername and add supername__define \ as the first line in the class definition. Both must be there. There is also JSON support, signals, abstract classes, etc.

    To create an object, just use W_NEW(classname, .x=1, .y=2,...). The initialization is based on struct initialization introduced in C11. It works nicely and everything not listed is set to zero.

    To call a method, use W_CALL(o,method)(1,2,3). It looks like a higher order function call but it is just a macro. It expands to ((o)->klass->method(o,1,2,3)) which is a really nice hack.

    See Documentation and the code itself.

    Since the framework needs some boilerplate code, I wrote a Perl script (wobject) that does the job. If you use that, you can just write

    class Point
        public int move_up(int steps)
        public void draw()
        read int x
        read int y
    

    and it will create the class specification file, class header, and a C file, which includes Point_impl.c where you implement the class. It saves quite a lot of work, if you have many simple classes but still everything is in C. wobject is a very simple regular expression based scanner which is easy to adapt to specific needs, or to be rewritten from scratch.

提交回复
热议问题