Thread: Simulating OOP with structs and function pointers?

  1. #1
    Registered User ITAmember's Avatar
    Join Date
    Mar 2009
    Location
    Nebraska
    Posts
    72

    Simulating OOP with structs and function pointers?

    First of all I do not want any crap about "why don't you use C++?". I need a lot of interfacing with assembly and I want to keep it as simple as possible, that means avoiding C++ at all costs. (please no commenting on that and just go along with my wishes, it's more complicated than I'm willing to explain)

    Would it be possible to define a struct in C that held value members and function points and use that as a OOP style class? I just seems to deceptively simple to work. Could I also simulate inheratence by just adding members of the super class onto the base class? Once again seems deceptively simple. Any key OOP features I'm missing besides operator overloading?

    Thanks in advance.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    1 - Can I define a struct that has function pointers as members? - Yes.
    2 - Can I make a structure have other structures as members? - Yes.

    Is that what you're asking?


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, you can. Proof of that is that the first version of Bjarne's C++ compiler didn't generate assembler, it generated C code, to be compiled by the C compiler.

    Obviously, as you mention, operator overloading and templates require processing before the C compiler can take over. But all the basic features such as virtual functions and inheritance can be solved in C. Multiple inheritance gets a bit messy, and if the compiler doesn't support anonymous [nameless] structs in other structs.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User ITAmember's Avatar
    Join Date
    Mar 2009
    Location
    Nebraska
    Posts
    72
    So C++ is really just a redundancy?

    EDIT:

    I'm just asking this because it makes no sense (in my opinion) to use a redundant (and slower) langauge.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by ITAmember View Post
    So C++ is really just a redundancy?
    It brings convenience - and it has better error checking.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    ... Why don't you just use C++? j/k

    Yes - what you're asking is very possible. One of the things I like about C is your style can be procedural, functional, or object-oriented. It's nice. In fact, it's my understanding that there are parts of the Linux kernel (which, like your project, needs to remain simple and use a lot of assembly) has parts that almost resemble the use of classes. I've never seen the actual code - but using C in an OOP style is certainly possible.

  7. #7
    Registered User ITAmember's Avatar
    Join Date
    Mar 2009
    Location
    Nebraska
    Posts
    72
    Question answered, thanks!

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by ITAmember View Post
    First of all I do not want any crap about "why don't you use C++?".
    No worries.

    Would it be possible to define a struct in C that held value members and function points and use that as a OOP style class?
    You can put a function pointer in a struct, but it can't point to anything by default AFAIK. So that means you can't define the function in the struct, and you will have to assign the function pointer "per object" if you are trying to use a struct like a class. So I would say, don't bother trying to emulate OOP style coding to that extent.

    There is no problem emulating OOP funtionality tho. Since you are the programmer, hopefully you should be able to remember which functions do what, without having them associated as method calls. So rather that calling "mystruct.new(parameters)":
    Code:
    struct {
          char *data;
          int num;
    } mystruct;
    
    mystruct *initialize_object(char *data, int num) {      
           struct mystruct *ptr=malloc(sizeof(struct mystruct));
           ptr->data = data;
           ptr->num = num;
           return ptr;
    }
    Any methods you want "associated" with the class would just be:
    Code:
    whatevertype class_method(struct mystruct *ptr) {
            [perform operations]
            return as appropriate;
    }
    If you keep your function definitions in alphabetical order, you will have:
    Code:
    int myclass_method1(...);
    char myclass_method2(...);
    etc myclass_method3(...);
    and if you are really worried C is too confusing you can put these sets in separate header files or something
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Sean,

    Yes, Linux [and Windows] drivers use a "virtual member class" structure as the way to connect the open, read, write, and close functions of the specific driver implementation back into the generic driver framework.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Instead of this:

    Code:
    struct my_class
    {
        void (*func1)( struct my_class *, ... );
        void (*func2)( struct my_class *, ... );
        void (*func3)( struct my_class *, ... );
    };
    
    my_class *foo = new_my_class( ... );
    foo->func1( foo, ... );
    Do this:

    Code:
    struct my_class;
    
    struct my_class_vtable
    {
        void (*func1)( struct my_class *, ... );
        void (*func2)( struct my_class *, ... );
        void (*func3)( struct my_class *, ... );
    };
    
    struct my_class
    {
        struct my_class_vtable *vtable;
    };
    
    struct my_class *foo = new_my_class( ... );
    foo->vtable->func1( foo, ... );
    There is absolutely no point in wasting tons of memory keeping the function pointers in every instance of the "class."
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by brewbuck View Post
    There is absolutely no point in wasting tons of memory keeping the function pointers in every instance of the "class."
    IMO it is silly to use function pointers for this at all.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #12
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by MK27 View Post
    IMO it is silly to use function pointers for this at all.
    How will you implement virtuals then? Without virtuals, it's not OOP, it's just syntax.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MK27 View Post
    IMO it is silly to use function pointers for this at all.
    It is silly if there is no need for it - it's just extra overhead then. But if there is a need to do different things for different objects in the same outer function then function pointers is definitely the way to go. The other option is to have functions that do something like this:
    Code:
    int func(struct something *this)
    {
         if(this->type = type_a)
            do_type_a_work.... 
         else if (this->type = type_b)
             do_type_b_work...
    }
    That gets very messy very quickly [and yes, it may be possible to use switch here, but it's not fixing the REAL problem - which is that you need to determine what the type is, and then do the work necessary]. Imagiine that you have to do this in 5-6 or more different functions.

    With function pointers, you can simply call the function belonging to the struct. No messing about with if-statements.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by matsp View Post
    It is silly if there is no need for it - it's just extra overhead then. But if there is a need to do different things for different objects in the same outer function
    Just submit the instance of the struct/object to that function. That's what you're doing anyway. With the pointer, if you modify the functions parameters, you now have to change the prototype AND the function pointer in the struct. Yuck.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MK27 View Post
    Just submit the instance of the struct/object to that function. That's what you're doing anyway. With the pointer, if you modify the functions parameters, you now have to change the prototype AND the function pointer in the struct. Yuck.
    I don't think you understood what I meant. Say we have this:
    Code:
    struct animal
    {
         void (*talk)(struct animal *this);
    };
    
    
    struct cat
    {
         struct animal;
    };
    
    struct dog
    {
        struct animal;
    };
    
    void dogtalk(struct animal *this)
    {
        printf("Bark, bark!\n");
    }
    
    void cattalk(struct animal *this)
    {
         printf("Meow, meow\n");
    }
    
    void dog_construct(struct dog *this)
    {
         this->talk = dogtalk;
    }
    
    void cat_construct(struct cat *this)
    {
         this->talk = cattalk;
    }
    
    int main()
    {
         struct cat c;
         struct dog d;
    
         cat_construct(&c);
         dog_contstruct(&d);
    
         d.talk((struct animal *)&d);
         c.talk((struct animal *)&c);
    }
    Now, imagine you have half a dozen different functions, with half a dozen different animals - it gets very messy.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Passing pointers to structs as function arguments
    By Da-Nuka in forum C++ Programming
    Replies: 2
    Last Post: 06-13-2005, 12:10 PM
  2. passing structs & pointers to structs as arguments
    By Markallen85 in forum C Programming
    Replies: 6
    Last Post: 03-16-2004, 07:14 PM
  3. Replies: 5
    Last Post: 02-20-2004, 09:36 AM
  4. pointers to pointers within structs
    By Lord_azrael99 in forum C Programming
    Replies: 2
    Last Post: 08-28-2003, 04:29 AM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM

Tags for this Thread