What is the equivalent of class in pure C

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.


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.


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.

Tags:

C

Oop

Class