As a learning experience I'm trying to achieve simple class inheritence in C, among other OOP features.
So far I've been able to properly hide "private" functions and attributes of a class from the outer context.
Let's consider Point as a simple class example. It is made up of three modules:
public.h
#ifndef POINT_PUBLIC_H_
#define POINT_PUBLIC_H_
typedef struct Point Point;
Point* newPoint(const int x, const int y);
int getX(const Point* self);
int getY(const Point* self);
void setX(Point* self, const int x);
void setY(Point* self, const int y);
void printPoint(const Point* self);
#endif
This is basically the public interface of Point and it also defines the type Point referring to a struct declared in another module, hiding its attributes.
protected.h
#ifndef POINT_PROTECTED_H_
#define POINT_PROTECTED_H_
struct Point {
int x;
int y;
};
#endif
It hosts the actual struct definition and it could also contain prototypes to functions meant to be accessible only by inhereting classes.
And then there's implementation.c which includes both public.h and protected.h and contains the actual code of public, protected and private functions.
This works great, but what if I wanted to define a Circle class, which extends Point?
I envisioned something like this:
#ifndef CIRCLE_PROTECTED_H_
#define CIRCLE_PROTECTED_H_
#include "../Point/protected.h"
struct Circle {
Point parent;
int radius;
};
#endif
Since the public functions of Point expect a pointer to Point, and since the first attribute of the Circle struct is a Point (not a pointer to it), given a Circle* c
object, it becomes possible to do something like getX((Point*) c);
.
While this works fine, what I'm not happy about is that I can directly access the attributes to a Point object (including that one in the Circle struct of course) in the Circle modules.
Moving the struct definition to the implementation module would make its attributes completely private, but then I wouldn't be able to directly istantiate a Point object in order to set up the mechanism of inheritence.
Is there a way to make inheritence work while mantaining the privacy of the class that is being extended?
Point
with a (large enough) character buffer, pass this around and cast this to the real Point structure in functions/source files, that may know the definition. But I would never do that in production code ;)Point
fromCircle
is a good idea (in C). You have a graphics source set and then there is user code. The graphics code should know all about the implementation of all shapes and operations; the user code can use void pointers.