Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the equivalent of class in pure C

Tags:

c

oop

class

In OOP languages, we have classes. Is there an equivalent to class in pure C?

like image 574
Ruslan Avatar asked Apr 06 '16 07:04

Ruslan


3 Answers

There is none. This fact was the original motivation for the development of C++, back when C++ was called "C with Classes". The closest thing you can get is a struct.


There is a feature in C intended to facilitate a sort of pseudo-inheritance, but it doesn't come close to an actual object-oriented class system. A pointer to a struct can legally be cast to and from a pointer to the struct's first member, so you can sort of "extend" a struct type A by having another struct type B start with a member of type A.

For example, you can have a PyObject struct type and a bunch of struct types that all start with a PyObject member, say PyIntObject, PyDictObject, etc:

typedef struct {
    ...
} PyObject;

typedef struct {
    PyObject ob_base;
    // more members...
} PyIntObject;

typedef struct {
    PyObject ob_base;
    // more members...
} PyDictObject;

You could then pass PyIntObjects and PyDictObjects around with PyObject pointers and use the data in the PyObject part to tell what the type of the enclosing struct is.

As you may have guessed from the names, I've taken this example from Python, where this mechanism is used to implement Python's object-oriented type system on top of C.

like image 105
user2357112 supports Monica Avatar answered Nov 18 '22 02:11

user2357112 supports Monica


There is nothing equivalent to classes. Its a totally different paradigm. You can use structures in C. Have to code accordingly to make structures do the job.

like image 43
SamGhatak Avatar answered Nov 18 '22 01:11

SamGhatak


You can swap "Class" in C++ for "struct".

I'm not saying you should but one mans object is another mans struct with some functions that operate on that struct and where the first parameter to the function is the struct itself. Obviously C++ adds some extra bits. C and opaque pointers are also Objects and very useful ones at that.

#include <iostream>          

struct Cat {
public:
    Cat(int initialAge);     // constructor
    ~Cat();                  // destructor

    int GetAge();                
 private:                   // begin private section
    int itsAge;              // member variable
};

Cat::Cat(int initialAge) {
  itsAge = initialAge;
} 

int Cat::GetAge() {
  return itsAge;             
}

int main(void) {            
  Cat *cat = new Cat(1);     
  std::cout << "This cat declared as a struct is " << cat->GetAge() << " years old" <<std::endl;
  return 1;
}

You can achieve a similar thing in C with a bit more work... Header file is

#ifndef CAT_H
#define CAT_H
#include <stdlib.h>
#include <stdio.h>

typedef struct Cat Cat;

typedef struct CatOps {
  int (* GetAge )();
} CatOps;

struct Cat {
  void   * obj;
  CatOps * ops;
};

Cat * new_cat(int age);
void  delete_cat(Cat * cat);

#endif /* CAT_H */

.c file is

#include "cat.h"
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

typedef struct cat_obj {
  int age;
} cat_obj;

int get_age();

static CatOps CAT_OPS = { 
  .GetAge = get_age,
};

Cat * new_cat(int age) {
  Cat     * imp;
  cat_obj * obj;
  imp = malloc(sizeof(*imp));
  obj = malloc(sizeof(*obj));
  imp->obj = obj;
  imp->ops = &CAT_OPS;
  return (Cat*)imp;
}

void delete_cat(Cat *cat) {
  free(cat->obj);
  free(cat);
}

static void get_age(Cat *cat) {
  cat_obj *c = (cat_obj*)cat->obj;
}

Note, I've not tested it but if you know C/C++ you should recognize the idiom.

like image 6
Harry Avatar answered Nov 18 '22 01:11

Harry