Object Oriented C Programming

Possible duplicates:
Can you write object oriented code in C?
Object Oriented Template in C?

I remember reading some time ago about someone (I think it was Linus Torvalds) about how C ++ is a terrible language and how you can write object-oriented programs with C. What I thought about I do not really see how all object-oriented concepts carry over to C. Some things are pretty obvious. For example:

  • To emulate member functions, you can put function pointers in structures.
  • To emulate polymorphism, you can write a function that takes a variable number of arguments and does some voodoo depending on, say, sizeof parameter (s)

How would you emulate encapsulation and inheritance?

I suggest that encapsulation can be emulated by placing a nested structure in which private members are stored. It would be fairly easy to get around, but it could be called PRIVATE or something as obvious to signal that it is not intended to be used from outside the structure. What about inheritance?

+52
c oop
Feb 02 '10 at 0:25
source share
13 answers

You can implement polymorphism with regular functions and virtual tables (vtables). Here's a pretty neat system that I came up with (based on C ++) for programming exercises: alt text

Constructors allocate memory and then call the init function of the class in which the memory is initialized. Each init function must also contain a static vtable structure containing pointers to virtual functions (NULL for pure virtual). Derived functions of the init class call the function of the init superclass before doing anything else.

A very good API can be created by implementing shells of virtual functions (not to be confused with the functions that vtables points to) as follows (add a static inline in front of it if you do this in the header)

 int playerGuess(Player* this) { return this->vtable->guess(this); } 

Single inheritance can be accomplished by overusing the binary layout of the structure: alt text

Note that multiple inheritance is more messy, as you often have to adjust the pointer value when casting between hierarchy types.

Other type-specific data can also be added to virtual tables. Examples include runtime type information (for example, a type name as a string), a link to the vtable superclass, and a chain of destructors. You probably need virtual destructors where the destructor of the derived class lowers the object to its superclass, and then recursively calls the destructor of it, etc., until the destructor of the base class is reached and which finally frees the structure.

Encapsulation was accomplished by defining structures in player_protected.h and implementing functions (denoted by vtable) in player_protected.c and similarly for derived classes, but this is rather clumsy and this degrades performance (since virtual wrappers cannot be placed in headers), therefore I would recommend against this.

+75
Feb 02 2018-10-02T00
source share

Have you read the Bible on this subject? See Object Oriented C ...

+28
Feb 02 2018-10-02T00 00
source share

How would you emulate encapsulation and inheritance?

Encapsulation itself is the easiest part. Encapsulation is a design philosophy, it has nothing to do with the language and all the way you think about problems.

For example, the Windows FILE api is fully encapsulated. When you open the file, you return an opaque object that contains all the state information for the file "object". You pass this handle to each io apis file. Encapsulation is actually much better than C ++, because there is no public header file that people can look at and see the names of your private variables.

Inheritance is more complicated, but it’s not at all necessary for your code to be object oriented. In a sense, aggregation is better than inheritance anyway, and aggregation is as easy in C as it is in C ++. see this one for example.

In response to Neil, see Wikipedia for an explanation of why inheritance is not required for polymorphism.

Old-timers wrote us object-oriented code years before C ++ compilers were available; this is not a set of tools.

+8
Feb 02 2018-10-02T00
source share

Apple C-based CoreFoundation was written so that its “objects” could double as objects in Objective-C, the real language of OO. A fairly large subset of the framework is open source on Apple's website as CF-Lite . Perhaps this will be a useful case study within the framework of the main OS structure performed in this way.

+5
Feb 02 2018-10-02T00
source share

From a slightly higher height and considering the problem rather more unbiased than, as the basic principle of OOP can suggest, object-oriented programming means thinking about objects as with data with related functions. This does not necessarily mean that the function must be physically attached to the object, since it is in popular languages ​​that support the OOP paradigm, for example, in C ++:

 struct T { int data; int get_data() const { return data; } }; 

I would suggest taking a closer look at GTK + Object and Type System . This is a brilliant example of OOP implemented in the C programming language:

GTK + implements its own custom object system, which offers standard object-oriented functions such as inheritance and virtual function

The association may also be contractual and conditional.

Regarding encapsulation and data hiding methods, Opaque Pointer (or an opaque data type) can be popular and simple - you can pass it, but to load or save any information, you must call a related function that knows how to talk to an object hidden behind this opaque pointer.

Another similar but excellent Shadow Data type is check out this link where John Jagger gives an excellent explanation for this not-so-well-known technique.

+5
Feb 02 2018-10-02T00
source share

gtk and glib libraries use macros to create objects for different types.
add_widget (GTK_WIDGET (MyButton));
I can’t say how it was done, but you can read their source to find out how it is done.

+2
02 Feb. 2018-10-02T00 00Z
source share

See how the VFS layer in the Linux kernel works for an example inheritance pattern. File operations for various file systems “inherit” a set of common file operations functions (for example, generic_file_aio_read() , generic_file_llseek() ...), but can override them with their own implementations (for example, ntfs_file_aio_write() ).

+2
02 feb. 2018-10-02T00
source share

Definitely look at Objective-C.

 typedef struct objc_object { Class isa; } *id; typedef struct objc_class { struct objc_class *isa; struct objc_class *super_class const char *name; long version; long info long instance_size; struct objc_ivar_list *ivars; struct objc_method_list **methodLists; struct objc_cache *cache; struct objc_protocol_list *protocols; } *Class; 

As you can see, inheritance information along with other details is stored in the class structure (conveniently, a class can also be considered as an object).

Objective-C suffers just like C ++ with encapsulation, because you need to publicly declare your variables. Straight C is much more flexible since you can simply return void pointers that only your module has internal access to, so encapsulation is much better in this regard.

I once wrote a basic OO C-style drawing program as part of a graphic course - I did not get to declaring the class, I just used the vtable pointer as the first element of the structure and implemented manual code inheritance. The optimal game with vtables at such a low level is that you can change the class’s behavior at runtime by changing several pointers or dynamically changing the class of objects. It was pretty easy to create all kinds of hybrid objects, fake multiple inheritance, etc.

+2
Feb 02 '10 at 1:51
source share

A good article and discussion regarding Objective-C here:

http://cocoawithlove.com/2009/10/objective-c-niche-why-it-survives-in.html

+2
Feb 02 '10 at 9:09
source share

For a great example of object-oriented programming in C, look at the source of POV-Ray a few years ago - version 3.1g is especially good. Of course, "objects" were a structure with function pointers. Macros were used to provide basic methods and data for an abstract object, and derived classes were structures that began with this macro. However, there was no attempt to deal with the private / public. All that needed to be seen was in .h files, and implementation details were in .c files, with the exception of many exceptions.

There were some neat tricks that I don’t see how to port to C ++ - for example, converting one class to another, but similar on the fly by reassigning function pointers. Simple today dynamic languages. I forgot the details; I think it could be CSG intersections and union objects.

http://www.povray.org/

+1
Feb 02 2018-10-02T00
source share

Interesting story. Cfront , C ++ source - the implementation outputs C code, and then requires a C compiler to actually generate the final code. So, everything that can be expressed in C ++ can be written as C.

+1
Feb 02 2018-10-02T00 00Z
source share

One way to handle inheritance is by having nested structures:

 struct base { ... }; void method_of_base(base *b, ...); struct child { struct base base_elements; ... }; 

Then you can make such calls:

 struct child c; method_of_base(&c.b, ...); 
+1
Feb 02 2018-10-02T00
source share

You might want to look at Objective-C, which is pretty much what it does. This is just an interface that compiles Objective-C OO code into C.

0
Feb 02 2018-10-02T00
source share



All Articles