can you writeall about you...

Can you write a short paragraph about something that you have learnt this summer
Well ,nothing……
为您推荐:
其他类似问题
扫描下载二维码oop - Can you write object-oriented code in C? - Stack Overflow
to customize your list.
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
J it only takes a minute:
Join the Stack Overflow community to:
Ask programming questions
Answer and help your peers
Get recognized for your expertise
Can you write object-oriented code in C? Especially with regard to polymorphism.
See also Stack Overflow question .
Yes. In fact Axel Schreiner provides
"Object-oriented Programming in ANSI-C" for free which covers the subject quite thoroughly.
Since you're talking about polymorphism then yes, you can, we were doing that sort of stuff years before C++ came about.
Basically you use a struct to hold both the data and a list of function pointers to point to the relevant functions for that data.
So, in a communications class, you would have an open, read, write and close call which would be maintained as four function pointers in the structure, alongside the data for an object, something like:
typedef struct {
int (*open)(void *self, char *fspec);
int (*close)(void *self);
int (*read)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
int (*write)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
// And data goes here.
tCommClass commRs232;
commRs232.open = &rs232O
commRs232.write = &rs232W
tCommClass commT
commTcp.open = &tcpO
commTcp.write = &tcpW
Of course, those code segments above would actually be in a "constructor" such as rs232Init().
When you 'inherit' from that class, you just change the pointers to point to your own functions. Everyone that called those functions would do it through the function pointers, giving you your polymorphism:
int stat = (commTcp.open)(commTcp, ":5000");
Sort of like a manual vtable.
You could even have virtual classes by setting the pointers to NULL -the behaviour would be slightly different to C++ (a core dump at run-time rather than an error at compile time).
Here's a piece of sample code that demonstrates it. First the top-level class structure:
#include &stdio.h&
// The top-level class.
typedef struct _tCommClass {
int (*open)(struct _tCommClass *self, char *fspec);
Then we have the functions for the TCP 'subclass':
// Function for the TCP 'class'.
static int tcpOpen (tCommClass *tcp, char *fspec) {
printf ("Opening TCP: %s\n", fspec);
static int tcpInit (tCommClass *tcp) {
tcp-&open = &tcpO
And the HTTP one as well:
// Function for the HTTP 'class'.
static int httpOpen (tCommClass *http, char *fspec) {
printf ("Opening HTTP: %s\n", fspec);
static int httpInit (tCommClass *http) {
http-&open = &httpO
And finally a test program to show it in action:
// Test program.
int main (void) {
tCommClass commTcp, commH
// Same 'base' class but initialised to different sub-classes.
tcpInit (&commTcp);
httpInit (&commHttp);
// Called in exactly the same manner.
status = (commTcp.open)(&commTcp, ":5000");
status = (commHttp.open)(&commHttp, "");
This produces the output:
Opening TCP: :5000
Opening HTTP:
so you can see that the different functions are being called, depending on the sub-class.
Namespaces are often done by doing:
stack_push(thing *)
instead of
stack::push(thing *)
struct into something like a
class you can turn:
class stack {
void push(thing *);
thing * pop();
static int this_is_here_as_an_example_
struct stack {
struct stack_type * my_
// Put the stuff that you put after private: here
struct stack_type {
void (* construct)(struct stack * this); // This takes uninitialized memory
struct stack * (* operator_new)(); // This allocates a new struct, passes it to construct, and then returns it
void (*push)(struct stack * this, thing * t); // Pushing t onto this stack
thing * (*pop)(struct stack * this); // Pops the top thing off the stack and returns it
int this_is_here_as_an_example_
}Stack = {
.construct = stack_construct,
.operator_new = stack_operator_new,
.push = stack_push,
.pop = stack_pop
// All of these functions are assumed to be defined somewhere else
struct stack * st = Stack.operator_new(); // Make a new stack
if (!st) {
// Do something about it
// You can use the stack
stack_push(st, thing0); // This is a non-virtual call
Stack.push(st, thing1); // This is like casting *st to a Stack (which it already is) and doing the push
st-&my_type.push(st, thing2); // This is a virtual call
I didn't do the destructor or delete, but it follows the same pattern.
this_is_here_as_an_example_only is like a static class variable -- shared among all instances of a type. All methods are really static, except that some take a this *
I believe that besides being useful in its own right, implementing OOP in C is an excellent way to learn OOP and understand its inner workings. Experience of many programmers has shown that to use a technique efficiently and confidently, a programmer must understand how the underlying concepts are ultimately implemented. Emulating classes, inheritance, and polymorphism in C teaches just this.
To answer the original question, here are a couple resources that teach how to do OOP in C:
< blog post "Object-based programming in C" shows how to implement classes and single inheritance in portable C:
Application Note ""C+"—Object Oriented Programming in C" shows how to implement classes, single inheritance, and late binding (polymorphism) in C using preprocessor macros:
, the example code is available from
I've seen it done.
I wouldn't recommend it.
C++ originally started this way as a preprocessor that produced C code as an intermediate step.
Essentially what you end up doing is create a dispatch table for all of your methods where you store your function references.
Deriving a class would entail copying this dispatch table and replacing the entries that you wanted to override, with your new "methods" having to call the original method if it wants to invoke the base method.
Eventually, you end up rewriting C++.
Sure that is possible. This is what , the framework that all of
is based on, does.
The C stdio FILE sub-library is an excellent example of how to create abstraction, encapsulation, and modularity in unadulterated C.
Inheritance and polymorphism - the other aspects often considered essential to OOP - do not necessarily provide the productivity gains they promise and
that they can actually hinder development and thinking about the problem domain.
Trivial example with an Animal and Dog: You mirror C++'s vtable mechanism (largely anyway). You also separate allocation and instantiation (Animal_Alloc, Animal_New) so we don't call malloc() multiple times. We must also explicitly pass the this pointer around.
If you were to do non-virtual functions, that's trival. You just don't add them to the vtable and static functions don't require a this pointer. Multiple inheritance generally requires multiple vtables to resolve ambiguities.
Also, you should be able to use setjmp/longjmp to do exception handling.
struct Animal_Vtable{
typedef void (*Walk_Fun)(struct Animal *a_This);
typedef struct Animal * (*Dtor_Fun)(struct Animal *a_This);
Walk_Fun W
Dtor_Fun D
struct Animal{
struct Dog{
char *N // Mirror member variables for easy access
void Animal_Walk(struct Animal *a_This){
printf("Animal (%s) walking\n", a_This-&Name);
struct Animal* Animal_Dtor(struct Animal *a_This){
printf("animal::dtor\n");
return a_T
Animal *Animal_Alloc(){
return (Animal*)malloc(sizeof(Animal));
Animal *Animal_New(Animal *a_Animal){
a_Animal-&vtable.Walk = Animal_W
a_Animal-&vtable.Dtor = Animal_D
a_Animal-&Name = "Anonymous";
return a_A
void Animal_Free(Animal *a_This){
a_This-&vtable.Dtor(a_This);
free(a_This);
void Dog_Walk(struct Dog *a_This){
printf("Dog walking %s (%s)\n", a_This-&Type, a_This-&Name);
Dog* Dog_Dtor(struct Dog *a_This){
// Explicit call to parent destructor
Animal_Dtor((Animal*)a_This);
printf("dog::dtor\n");
return a_T
Dog *Dog_Alloc(){
return (Dog*)malloc(sizeof(Dog));
Dog *Dog_New(Dog *a_Dog){
// Explict call to parent constructor
Animal_New((Animal*)a_Dog);
a_Dog-&Type = "Dog type";
a_Dog-&vtable.Walk = (Animal_Vtable::Walk_Fun) Dog_W
a_Dog-&vtable.Dtor = (Animal_Vtable::Dtor_Fun) Dog_D
return a_D
int main(int argc, char **argv){
Base class:
Animal *a_Animal = Animal_New(Animal_Alloc());
Animal *a_Animal = (Animal*)Dog_New(Dog_Alloc());
a_Animal-&vtable.Walk(a_Animal);
Animal_Free(a_Animal);
PS. This is tested on a C++ compiler, but it should be easy to make it work on a C compiler.
This has been interesting to read. I have been pondering the same question myself, and the benefits of thinking about it are this:
Trying to imagine how to implement OOP concepts in a non-OOP language helps me understand the strengths of the OOp language (in my case, C++). This helps give me better judgement about whether to use C or C++ for a given type of application -- where the benefits of one out-weighs the other.
In my browsing the web for information and opinions on this I found an author who was writing code for an embedded processor and only had a C compiler available:
In his case, analyzing and adapting OOP concepts in plain C was a valid pursuit. It appears he was open to sacrificing some OOP concepts due to the performance overhead hit resulting from attempting to implement them in C.
The lesson I've taken is, yes it can be done to a certain degree, and yes, there are some good reasons to attempt it.
In the end, the machine is twiddling stack pointer bits, making the program counter jump around and calculating memory access operations.
From the efficiency standpoint, the fewer of these calculations done by your program, the better... but sometimes we have to pay this tax simply so we can organize our program in a way that makes it least susceptible to human error. The OOP language compiler strives to optimize both aspects. The programmer has to be much more careful implementing these concepts in a language like C.
Check out .
It's meant to be OO in C and one implementation of what you're looking for.
If you really want OO though, go with C++ or some other OOP language.
GObject can be really tough to work with at times if you're used to dealing with OO languages, but like anything, you'll get used to the conventions and flow.
You may find it helpful to look at Apple's documentation for its Core Foundation set of APIs. It is a pure C API, but many of the types are bridged to Objective-C object equivalents.
You may also find it helpful to look at the design of Objective-C itself. It's a bit different from C++ in that the object system is defined in terms of C functions, e.g. objc_msg_send to call a method on an object. The compiler translates the square bracket syntax into those function calls, so you don't have to know it, but considering your question you may find it useful to learn how it works under the hood.
There are several techniques that can be used. The most important one is more how to split the project. We use an interface in our project that is declared in a .h file and the implementation of the object in a .c file. The important part is that all modules that include the .h file see only an object as a void *, and the .c file is the only module who knows the internals of the structure.
Something like this for a class we name FOO as an example:
In the .h file
#ifndef FOO_H_
#define FOO_H_
typedef struct FOO_type FOO_
/* That's all the rest of the program knows about FOO */
/* Declaration of accessors, functions */
FOO_type *FOO_new(void);
void FOO_free(FOO_type *this);
void FOO_dosomething(FOO_type *this, param ...):
char *FOO_getName(FOO_type *this, etc);
The C implementation file will be something like that.
#include &stdlib.h&
#include "FOO.h"
struct FOO_type {
whatever...
FOO_type *FOO_new(void)
FOO_type *this = calloc(1, sizeof (FOO_type));
FOO_dosomething(this, );
So I give the pointer explicitly to an object to every function of that module. A C++ compiler does it implicitly, and in C we write it explicitly out.
I really use this in my programs, to make sure that my program does not compile in C++, and it has the fine property of being in another color in my syntax highlighting editor.
The fields of the FOO_struct can be modified in one module and another module doesn't even need to be recompiled to be still usable.
With that style I already handle a big part of the advantages of OOP (data encapsulation). By using function pointers, it's even easy to implement something like inheritance, but honestly, it's really only rarely useful.
Object oriented C, can be done, I've seen that type of code in production in Korea, and it was the most horrible monster I'd seen in years (this was like last year(2007) that I saw the code).
So yes it can be done, and yes people have done it before, and still do it even in this day and age. But I'd recommend C++ or Objective-C, both are languages born from C, with the purpose of providing object orientation with different paradigms.
If you are convinced that an OOP approach is superior for the problem you are trying to solve, why would you be trying to solve it with a non-OOP language? It seems like you're using the wrong tool for the job. Use C++ or some other object-oriented C variant language.
If you are asking because you are starting to code on an already existing large project written in C, then you shouldn't try to force your own (or anyone else's) OOP paradigms into the project's infrastructure. Follow the guidelines that are already present in the project. In general, clean APIs and isolated libraries and modules will go a long way towards having a clean OOP-ish design.
If, after all this, you really are set on doing OOP C, read
Yes, you can. People were writing object-oriented C before C++ or
came on the scene. Both C++ and Objective-C were, in parts, attempts to take some of the OO concepts used in C and formalize them as part of the language.
Here's a really simple program that shows how you can make something that looks-like/is a method call (there are better ways to do this. This is just proof the language supports the concepts):
#include&stdio.h&
struct foobarbaz{
int (*exampleMethod)(int, int);
int addTwoNumbers(int a, int b){
return a+b;
int main()
// Define the function pointer
int (*pointerToFunction)(int, int) = addTwoN
// Let's make sure we can call the pointer
int test = (*pointerToFunction)(12,12);
printf ("test: %u \n",
// Now, define an instance of our struct
// and add some default values.
fbb.three = 3;
// Now add a "method"
fbb.exampleMethod = addTwoN
// Try calling the method
int test2 = fbb.exampleMethod(13,36);
printf ("test2: %u \n",
printf("\nDone\n");
Of course, it just won't be as pretty as using a language with built-in support. I've even written "object-oriented assembler".
A little OOC code to add:
#include &stdio.h&
struct Node {
void print() {
printf("Hello from an object-oriented C method!");
struct Tree {
struct Node * NIL;
void (*FPprint)(void);
struct Node *
struct Node NIL_t;
} TreeA = {&TreeA.NIL_t,print};
int main()
struct Tree TreeB;
TreeB = TreeA;
TreeB.FPprint();
You can fake it using function pointers, and in fact, I think it is theoretically possible to compile C++ programs into C.
However, it rarely makes sense to force a paradigm on a language rather than to pick a language that uses a paradigm.
There is an example of inheritance using C in Jim Larson's 1996 talk given at the
by Laurent Deniau
Which articles or books are good to use OOP concepts in C?
Dave Hanson's
is excellent on encapsulation and naming and very good on use of function pointers.
Dave does not try to simulate inheritance.
OOP is only a paradigm which place datas as more important than code in programs. OOP is not a language. So, like plain C is a simple language, OOP in plain C is simple too.
One thing you might want to do is look into the implementation of the
toolkit for . Sure it is getting long in the tooth, but many of the structures used were designed to work in an OO fashion within traditional C. Generally this means adding an extra layer of indirection here and there and designing structures to lay over each other.
You can really do lots in the way of OO situated in C this way, even though it feels like it some times, OO concepts did not spring fully formed from the mind of #include&favorite_OO_Guru.h&. They really constituted many of the established best practice of the time. OO languages and systems only distilled and amplified parts of the programing zeitgeist of the day.
I've been digging this for one year:
As the GObject system is hard to use with pure C, I tried to write some nice macros to ease the OO style with C.
#include "OOStd.h"
CLASS(Animal) {
STATIC(Animal);
static int Animal_load(Animal *THIS,void *name) {
THIS-&name =
ASM(Animal, Animal_load, NULL, NULL, NULL)
CLASS_EX(Cat,Animal) {
STATIC_EX(Cat, Animal);
static void Meow(Animal *THIS){
printf("Meow!My name is %s!\n", THIS-&name);
static int Cat_loadSt(StAnimal *THIS, void *PARAM){
THIS-&talk = (void *)M
ASM_EX(Cat,Animal, NULL, NULL, Cat_loadSt, NULL)
CLASS_EX(Dog,Animal){
STATIC_EX(Dog, Animal);
static void Woof(Animal *THIS){
printf("Woof!My name is %s!\n", THIS-&name);
static int Dog_loadSt(StAnimal *THIS, void *PARAM) {
THIS-&talk = (void *)W
ASM_EX(Dog, Animal, NULL, NULL, Dog_loadSt, NULL)
int main(){
Animal *animals[4000];
StAnimal *f;
int i = 0;
for (i=0; i&4000; i++)
if(i%2==0)
animals[i] = NEW(Dog,"Jack");
animals[i] = NEW(Cat,"Lily");
f = ST(animals[0]);
for(i=0; i&4000; ++i) {
f-&talk(animals[i]);
for (i=0; i&4000; ++i) {
DELETE0(animals[i]);
Here is my project site (I don't have enough time to write en. doc,however the doc in chinese is much better).
The answer to the question is 'Yes, you can'.
Object-oriented C (OOC) kit is for those who want to program in an object-oriented manner, but sticks on the good old C as well. OOC implements classes, single and multiple inheritance, exception handling.
o Uses only C macros and functions, no language extensions required! (ANSI-C)
o Easy-to-read source code for your application. Care was taken to make things as simple as possible.
o Single inheritance of classes
o Multiple inheritance by interfaces and mixins (since version 1.3)
o Implementing exceptions (in pure C!)
o Virtual functions for classes
o External tool for easy class implementation
For more details, visit .
I propose to use Objective-C, which is a superset of C.
While Objective-C is 30 years old, it allows to write elegant code.
for yet another twist on OOP in C. It emphasizes instance data for reentrancy using just native C. Multiple inheritance is done manually using function wrappers. Type safety is maintained. Here is a small sample:
typedef struct _peeker
symbols_t *
// inherited instance
(*push) ( SELF *d, symbol_t *symbol );
(*peek) ( SELF *d, int level );
( SELF *d );
(*get_line_number) ( SELF *d );
} peeker_t, SlkT
#define push(self,a)
(*self).push(self, a)
#define peek(self,a)
(*self).peek(self, a)
#define get(self)
(*self).get(self)
#define get_line_number(self)
(*self).get_line_number(self)
INSTANCE_METHOD
(get_line_number) ( peeker_t *d )
d-&scan.line_
InitializePeeker ( peeker_t
symbols_t *symbols,
InitializeScanner ( &peeker-&scan, trace, symbols, log, list );
peeker-&log =
peeker-&sym =
peeker-&pk.current = peeker-&pk.
peeker-&pk.count = 0;
peeker-&trace =
peeker-&get_line_number = get_line_
peeker-&push =
peeker-&get =
peeker-&peek =
I'm a bit late to the party, but I want to share my experience on the topic: I work with embedded stuff these days, and the only (reliable) compiler I have is C, so that I want to apply object-oriented approach in my embedded projects written in C.
Most of the solutions I've seen so far use typecasts heavily, so we lose type safety: compiler won't help you if you make a mistake. This is completely unacceptable.
Requirements that I have:
Avoid typecasts as much as possible, so we don'
Polymorphism: we should be able to use virtual methods, and user of the class should not be aware whether some particular meth
Multiple inheritance: I don't use it often, but sometimes I really want some class to implement multiple interfaces (or to extend multiple superclasses).
I've explained my approach in detail in this article: ; plus, there is an utility for autogeneration of boilerplate code for base and derived classes.
It's seem like people are trying emulate the C++ style using C. My take is that doing object-oriented programming C is really doing struct-oriented programming. However, you can achieve things like late binding, encapsulation, and inheritance. For inheritance you explicitly define a pointer to the base structs in your sub struct and this is obviously a form of multiple inheritance. You'll also need to determine if your
//private_class.h
struct private_
extern struct private_class * new_private_class();
extern int ret_a_value(struct private_class *, int a, int b);
extern void delete_private_class(struct private_class *);
void (*late_bind_function)(struct private_class *p);
//private_class.c
struct inherited_class_1;
struct inherited_class_2;
struct private_class {
struct inherited_class_1 *p1;
struct inherited_class_2 *p2;
struct inherited_class_1 * new_inherited_class_1();
struct inherited_class_2 * new_inherited_class_2();
struct private_class * new_private_class() {
struct private_class *p;
p = (struct private_class*) malloc(sizeof(struct private_class));
p-&p1 = new_inherited_class_1();
p-&p2 = new_inherited_class_2();
int ret_a_value(struct private_class *p, int a, int b) {
return p-&a + p-&b + a +
void delete_private_class(struct private_class *p) {
//release any resources
//call delete methods for inherited classes
struct private_class *p;
p = new_private_class();
late_bind_function = &implementation_
delete_private_class(p);
compile with c_compiler main.c inherited_class_1.obj inherited_class_2.obj
private_class.obj.
So the advice is to stick to a pure C style and not try to force into a C++ style. Also this way lends itself to a very clean way of building an API.
Yes, but I have never seen anyone attempt to implement any sort of polymorphism with C.
protected by
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10
on this site (the ).
Would you like to answer one of these
Not the answer you&#39;re looking for?
Browse other questions tagged
Stack Overflow works best with JavaScript enabled}

我要回帖

更多关于 all about you 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信