Struggling with C coming from Object Oriented land

2019-01-11 03:47发布

When I am presented with programming problems, I naturally start breaking them up into logical objects in my head. Who has what responsibility, who owns what, who derives from what, etc.

I am struggling with C. I just don't get how to do things in a Procedural Language.

Can an experienced C programmer help explain how I should think about my programs during design time?

For example, I want to write my own Semaphore class. I would naturally need a Queue data structure for my program, which I would like to write myself as well. If I needed to do this in Java or C#, I could simply whip up a quick Queue class and create a new instance of it in my Semaphore class.

But in C, there aren't objects. So do I have to inline all the behavior of my Queue data structure?

Can someone help me "get it"?

Related: what is the best way to plan and organize development of an application in c

10条回答
男人必须洒脱
2楼-- · 2019-01-11 04:05

I would amend S. Lott's answer to use an opaque pointer to perform data hiding of the members of the struct:

  1. Define your class however you want using normal OO design.
  2. Member variables of your class go into a C language struct.
  3. In the header file, you do not want to expose the member variables of your object (since these would be "private" in an OO language). Instead, use an opaque pointer, i.e.
    typedef struct mystruct_s *mystruct_t; // first argument to all your methods
  4. For all the methods you want to be "public", put their signatures in your .h file. Method bodies should go into the .c file, and "private" methods should be only defined in the .c file and also declared static so their symbols do not collide with symbols defined in other files.

Clever naming conventions like underscores are unnecessary using this method, but it means that all your member variables will be private. Functions can be public or private, although public functions they are part of a global namespace so you might want to qualify their names with a "package" name like mystruct_push(), mystruct_pop(), etc.

You also need to make it clear if the caller or the library is responsible for calling malloc() and free(). Most likely you will have mystruct_t *create() and void destroy(mystruct_t *target) methods.

查看更多
Animai°情兽
3楼-- · 2019-01-11 04:06

Check out the Lua C api. It has been my guiding light as far as C interface design goes. Every function takes a Lua state as a leading argument which becomes your "this". Inheritance is a little trickier but Chipmunk manages to do a pretty good job exposing functions that take a generic shape structs and work out the details of which function is actually called via a "klass". You can often exploit void* to have functions take different types (structs) the way you would overload in OO. It can feel a little hackish at times but works well.

查看更多
我只想做你的唯一
5楼-- · 2019-01-11 04:09

You can do derived classes also with C:

Derived classes in C - What is your favorite method?

查看更多
爷、活的狠高调
6楼-- · 2019-01-11 04:11

I second the suggestions for doing "Poor man's OO in C." I also think you might benefit from taking some time to see how Perl's OO works. Basically OO is accomplished in Perl by having the interpreter supply every method with the instance as an implicit first parameter. You'll want to do the same in C, explicitly, and use really, really good code organization since the compiler will not enforce good encapsulation for you.

By the way, you can enforce keeping the members of your structs private by using opaque pointers. I seem to recall that the GNU programming standards and recommendations included a technique for doing this by basically casting everything to void* when it was passed around, then using typedefs to name each specific type of opaque pointer that was supposed to be passed. (i.e., each "class")

查看更多
在下西门庆
7楼-- · 2019-01-11 04:15
登录 后发表回答