Object-oriented C language

I will explain how to write C language in an object-oriented manner.

An object-oriented language, in my interpretation, is a language that makes it easier to use object-oriented thinking.

In other words, object-oriented programming can be done in any programming language, but there is a programming language that makes it easier to do.

When I write the conclusion, "It can be object-oriented even in C language! The description is a little troublesome."

The

class is a structure

The class corresponds to structure. The fields correspond to the member variables of the structure. To solve problems such as header cross-references, we use aliases in typedef statements (see type declaration headers for this technique. please).

// Give strcut myapp_lib the alias MYAPP_LIB
typedef struct myapp_lib MYAPP_LIB;

// The class corresponds to the structure
struct myapp_lib {
  // Fields are member variables
  int32_t flag;
};;

Constructor is a function

A constructor is a function that returns an object. On this page, we will refer to pointers that point to the memory areas of structures that are dynamically allocated to memory as objects.

// Constructor is a function
MYAPP_LIB * MYAPP_LIB_new () {
  // Create an object with dynamic memory allocation
  MYAPP_LIB * self = calloc (sizeof (MYAPP_LIB), 1);
  
  // return an object
  return self;
}

// Constructor that can set flags
MYAPP_LIB * MYAPP_LIB_new_with_flag (int32_t flag) {
  
  MYAPP_LIB * self = MYAPP_LIB_new ();
  self->flag= flag;
  
  return self;
}

The

method is a function that takes an object as the first argument

A method is a function that takes an object as its first argument.

// Set the flag
void MYAPP_LIB_set_flag (MYAPP_LIB * self, int32_t flag) {
  self->flag= flag;
}

// get the flag
int32_t MYAPP_LIB_get_flag (MYAPP_LIB * self) {
  return self->flag;
}

Destructor is a function

Destructors are functions. This has to be called manually.

void MYAPP_LIB_free (MYAPP_LIB * self) {
  
  // Free memory allocation
  free (self);
}

Object-oriented programming sample

This is a sample of object-oriented programming.

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

// Give strcut myapp_lib the alias MYAPP_LIB
typedef struct myapp_lib MYAPP_LIB;

// The class corresponds to the structure
struct myapp_lib {
  // Fields are member variables
  int32_t flag;
};;

// Constructor is a function
MYAPP_LIB * MYAPP_LIB_new () {
  // Create an object with dynamic memory allocation
  MYAPP_LIB * self = calloc (sizeof (MYAPP_LIB), 1);
  
  // return an object
  return self;
}

// Constructor that can set flags
MYAPP_LIB * MYAPP_LIB_new_with_flag (int32_t flag) {
  
  MYAPP_LIB * self = MYAPP_LIB_new ();
  self->flag= flag;
  
  return self;
}

// Set the flag
void MYAPP_LIB_set_flag (MYAPP_LIB * self, int32_t flag) {
  self->flag= flag;
}

// get the flag
int32_t MYAPP_LIB_get_flag (MYAPP_LIB * self) {
  return self->flag;
}

void MYAPP_LIB_free (MYAPP_LIB * self) {
  
  // Free memory allocation
  free (self);
}

int main (void) {
  // Object creation
  MYAPP_LIB * myapp_lib = MYAPP_LIB_new ();
  
  // Method call
  MYAPP_LIB_set_flag (myapp_lib, 5);
  int32_t myapp_lib_flag = MYAPP_LIB_get_flag (myapp_lib);
  printf("%d\n", myapp_lib_flag);
  
  // Release the object
  MYAPP_LIB_free (myapp_lib);
}

Split compilation support-Object-oriented programming sample

Let's support split compilation of object-oriented programming samples. With this, it is safe even if the C language program becomes a big program in the actual battle.

myapp_typedecl.h

#ifndef MYAPP_TYPEDECL_H
#define MYAPP_TYPEDECL_H

// Give strcut mylib the alias MYLIB
typedef struct myapp_lib MYAPP_LIB;

#endif

myapp_lib.h

#ifndef MYAPP_LIB_H
#define MYAPP_LIB_H

#include "myapp_typedecl.h"

struct myapp_lib {
  int32_t flag;
};;

MYAPP_LIB * MYAPP_LIB_new ();
MYAPP_LIB * MYAPP_LIB_new_with_flag (int32_t flag);
void MYAPP_LIB_set_flag (MYAPP_LIB * self, int32_t flag);
int32_t MYAPP_LIB_get_flag (MYAPP_LIB * self);
void MYAPP_LIB_free (MYAPP_LIB * self);

#endif

myapp_lib.c

#include <stdlib.h>

#include "myapp_lib.h"

// Constructor is a function
MYAPP_LIB * MYAPP_LIB_new () {
  // Create an object with dynamic memory allocation
  MYAPP_LIB * self = calloc (sizeof (MYAPP_LIB), 1);
  
  // return an object
  return self;
}

// Constructor that can set flags
MYAPP_LIB * MYAPP_LIB_new_with_flag (int32_t flag) {
  
  MYAPP_LIB * self = MYAPP_LIB_new ();
  self->flag= flag;
  
  return self;
}

// Set the flag
void MYAPP_LIB_set_flag (MYAPP_LIB * self, int32_t flag) {
  self->flag= flag;
}

// get the flag
int32_t MYAPP_LIB_get_flag (MYAPP_LIB * self) {
  return self->flag;
}

void MYAPP_LIB_free (MYAPP_LIB * self) {
  
  // Free memory allocation
  free (self);
}

myapp.c

#include <stdio.h>
#include <stdint.h>

#include "myapp_lib.h"

int main (void) {
  // Object creation
  MYAPP_LIB * myapp_lib = MYAPP_LIB_new ();
  
  // Method call
  MYAPP_LIB_set_flag (myapp_lib, 5);
  int32_t myapp_lib_flag = MYAPP_LIB_get_flag (myapp_lib);
  printf("%d\n", myapp_lib_flag);
  
  // Release the object
  MYAPP_LIB_free (myapp_lib);
}

Compile / Link / Execute

gcc -c myapp_lib.c
gcc -c myapp.c
gcc -o myapp myapp.o myapp_lib.o
./myapp

Is it possible to inherit?

In C, it's not easy to manually implement the inheritance feature, so let's use delegation.

Transfer is a technique for storing objects that provide the required functionality in member variables.

Rest assured that there is no inheritance that will prevent you from failing to meet the functionality of your application.

Associated Information