1

I don't have much experience in Object oriented programming.I am trying to create an object in c which will have its own methods. I have declared structure which have pointers to function. All instance of this variable are going to point same function. But currently I need to initialize every instance of variable as in main (Line 1 and Line 2). So is there any method that will initialize its default value when I declare it?

#include <stdio.h>
#include <stdlib.h>

typedef struct serialStr Serial;

struct serialStr
{
    void(*init)(Serial*);
    void(*open)();
    void(*close)();
};


void open()
{
    printf("Open Port Success\n");
    return;
}

void close()
{
    printf("Close port Success\n");
    return;
}


void init(Serial* ptr)
{
    ptr->open   = open;
    ptr->close  = close;
}

int main()
{
    Serial serial,serial_2;

    serial.init = init;         
    serial.init(&serial);       // Line1

    serial_2.init = init;       
    serial_2.init(&serial_2);  // Line2

    serial.open();
    //rest of code
    serial.close();

    serial_2.open();
    serial_2.close();
    return 0;

}
3
  • 1
    In C there is none. You can choose to write a function that creates instances of objects. Otherwise you need to call init function explicitly. An easier alternative is to you C++ instead. Commented Apr 4, 2016 at 5:22
  • Why is this even tagged C++? This question is clearly about C and not C++. Commented Apr 4, 2016 at 5:28
  • Question is about object oriented approach which is not part of C. @Jens Gustedt. So Commented Dec 9, 2016 at 10:38

3 Answers 3

4

In C, the standard way would be to declare an initializer macro:

#define SERIAL_INITIALIZER { .init = init, .open = open, /* and others */ }

Serial serial = SERIAL_INITIALIZER;

In most cases in C there is simply no need for dynamic intialization of variables. You only need it for malloced objects.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, really helped out.
This isn't pure private encapsulation though, that macro has to be exposed to the caller. So I don't quite see how it would help the OO design, all it does is to hide the initializer list behind a public macro.
2

C++ add some automatization by calling constructor/destructor. In pure C is no way to do so. You should do all steps manually: create and initialize object (call constructor-like function for structure), call functions by pointers from the structure instance, call destructor (it should destroy the instance and free related resources).

If is no polymorphism in your task then use simple way - without pointers to functions, but each function (method) should take pointer to the object.

Common case example:

struct MyStruct
{
    // data
};

struct MyStruct* createMyStruct(/* maybe some input */)
{
    // create, init and return the structure instance
}

void destoyMyStruct(struct MyStruct* obj)
{
    // free resources and delete the instance
}

void doSomeAction(struct MyStruct* obj /* , some other data */)
{
    // ...
}

int main()
{
    struct MyStruct* object = createMyStruct();
    doSomeAction(object);
    destoyMyStruct(object);
    return 0;
}

Edit 1: macro is only for very simple cases and error-prone way.

Comments

0

Typically, you would do this through "opaque type". Meaning that you declare an object of incomplete type in your header:

typedef struct Serial Serial;

And then in the C file, you place the actual struct definition. This will hide the contents of the struct to the caller (private encapsulation). From your constructor, you could then set up private member functions:

struct Serial
{
    void(*init)(void);
    void(*open)(void);
    void(*close)(void);
};


// private member functions:
static void open (void);
...


// constructor:
Serial* SerialCreate (void)
{
  Serial* s = malloc(sizeof (*s));
  ...
  s->open = open;
  return s; 
}

This means that if you wish to inherit the class, you will only need to change the constructor.

Though of course, if you wish to implement true polymorphism, you don't want to change any code. You could solve this by passing the init function as parameter to the constructor.

header file:

typedef void init_func_t (void);

c file:

// constructor:
Serial* SerialCreate (init_func_t* init)
{
  Serial* s = malloc(sizeof (*s));
  ...

  init();

  return s; 
}

And then from the init function in the inherited class, set all private member functions.

1 Comment

It should be noted though, that implementing polymorphism in C is usually more trouble than it is worth. Focus on the most important things of OOD, which is creating autonomous objects that are only concerned with their own designated task, and that have limited dependencies of the outside world. Polymorphism is a rather peripheral OO feature, which is hyped up by academics. It can be useful and even powerful, but most of the time it trips itself over on its own major flaw: it is expecting the original program designer to be able to foresee the future.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.