The C equivalent would be to define a struct type for the Car
's attributes, and then define functions to manipulate objects of type Car
. That's essentially how the FILE
type works:
FILE *f = fopen("afile.txt", "r"); // open a file for reading
fgets(buffer, sizeof buffer, f); // read from a file
fprintf(f, "%d on the wall", bottles--); // write formatted text to the file
At no point to we manipulate objects of FILE
type directly; we just pass pass pointers back and forth.
There's no access control; you can't make some parts of a C struct public
and others private
; you can hide the implementation like so:
/** Car.h */
...
struct Car;
struct Car *createCar(void);
void deleteCar(struct Car **theCar);
int startCar(struct Car *theCar);
...
/** Car.c */
#include "Car.h"
...
struct Car {
char *make;
char *model;
int year;
...
};
struct Car *createCar(void)
{
struct Car *p = malloc(sizeof *p);
if (p)
{
... // initialize attributes
}
return p;
}
void deleteCar(struct Car **theCar)
{
free(*theCar);
*theCar = NULL;
}
void startCar(struct Car *theCar)
{
theCar->running = 1;
}
/** main.c */
#include "Car.h"
...
int main(void)
{
struct Car *c = createCar();
startCar(c);
...
deleteCar(&c);
}
In this example, main.c
only sees the forward declaration struct Car;
in Car.h
; since the type is incomplete, main
can only declare pointers to type struct Car
. In Car.c
, the struct type is completed with the definition struct Car {char *make; char *model; ...};
, so functions within Car.c
can access those members.