piclist 2008\07\04\081448a >
Thread: Implementing OOP features in C
www.piclist.com/techref/language/index.htm?key=c
picon face BY : Tomás Ó hÉilidheemail (remove spam text)




> The object/method paradigm can be simulated as:
>
>     ObjectName_MethodName()
>  

Do you mean ClassName instead of ObjectName?

> The method declaration gets put in the .h file. The big advantage of this
> naming convention, is that it answers the question "which file has the
> definition of this function"? It also tells the reader that it's a "public"
> function, exposed through the module's interface (.h file).
>  

When I started out learning about classes in C++, learning about
inheritance, polymorphism, all that stuff, I didn't like the explanation
that it "just works", so I decided to take some object-orientated C++
code and re-write it as C code, but with the aim of coming out with much
the same machine code.

So for a normal non-virtual function, instead of having the following in
C++:
   name_of_object.SomeMemberFunction(5);

I would have the following in C:
   NameOfClass_SomeMemberFunction(&name_of_object,5);

As you can see, the C function takes a pointer to the object as its
first parameter. This is how C++ compilers do it, they have a hidden
parameter at the beginning which is the "this" pointer.

When it came to implementing polymorphism, I did it exactly the same way
that C++ compilers do, i.e. using a V-Table. So if you had the following
in C++:

   class 3D_Shape {
   public:
       virtual double GetVolume(void) const;
   };

Then in C it would be:

   struct 3D_Shape;  /* Forward declaration */

   struct VTable_3D_Shape {
       double (*GetVolume)(struct 3D_Shape const *);
   };

   typedef struct 3D_Shape {
       VTable_3D_Shape const *pvtable;
   } 3D_Shape;

And so then you'd have the following C code:

   3D_Shape my_shape;

   3D_Shape_Constructor(&my_shape);  /* If there's a constructor */

   my_shape.pvtable->GetVolume(&my_shape);

If you don't like the above line, you could make a wrapper macro or
wrapper function that turns it into:

   3D_Shape_GetVolume(&my_shape);

Anyway the point of me getting into all this is to show that all that
fancy object-orientated stuff in C++ isn't that magical at all, and in
some places it amounts to nothing more than "syntactical sugar".
Contrast the following two code snippets for instance:

   MyClass my_object;
   my_object.DoSomething(5,3,2);

and:

   MyClass my_object;
   MyClass_Constructor(&my_object);
   MyClass_DoSomething(&my_object,5,3,2);
   MyClass_Destructor(&my_object);

Sure, it's handy that the constructor and destructor get called
automagically, but the actual member function call is nothing special --
it's just a different syntax. Taking some example object-orientated C++
code and converting it to C code can be quite easy if you get a little
practise... although admittedly things get a little hairy when you get
into multiple virtual inheritance.

> Private functions are named using the format:
>
>     __FunctionName()
>
> per Miro's suggestion.


I don't know if you're into writing standard-compliant code, but I'd
double check the Standard before I use double underscores at the start
of a function name. There's some stuff like that that's reserved for the
compiler's implementation. I don't it off by heart but double
underscores is ringing a few bells.

I wouldn't bother putting some sort of "private indicator" on them. I'd
just define them as "static" in the source file and put no declaration
in the header file. Other translation units will never see them. The
situation isn't much different in C++; you just write "private" in front
of it instead of "static".

>  Turns out, it's a good idea to use them to
> encapsulate even the small operations, like setting or clearing a byte. This
> may sound ridiculous, but the big advantage is that you essentially put the
> comments (what the function does) into the function name. It drastically
> improves readability, and the comments never get out of date or out of sync.
>
> Has anyone else used anything similar in the past? I'd love to hear about
> your experience.
>  

I started out programming in C++ before I started in C, so I was started
out on the bandwagon of "macroes are evil, use functions instead". I
went along this road for about five years maybe. The only time I would
opt to make a macro instead of a function was when I needed it to
evaluate to a compile-time constant. If this wasn't a requirement
though, I went with functions.

When I got into embedded programming though, I found out that functions
were the enemy. My original Connect4 game was too big to fit onto the
PIC16F684. I went through it and replaced a load of functions with
macroes, and then it fit snug.

Unless you have a very good compiler that does justice to inline
functions, then I'd shy away from making function for every little
operation.

<486E1415.8080408@lavabit.com> 7bit

In reply to: <023601c8dda1$0a4227c0$6f02a8c0@ws11>
See also: www.piclist.com/techref/language/index.htm?key=c
Reply You must be a member of the piclist mailing list (not only a www.piclist.com member) to post to the piclist. This form requires JavaScript and a browser/email client that can handle form mailto: posts.
Subject (change) Implementing OOP features in C

month overview.

new search...