xeland314/objects-in-C

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Basado en el libro Object-oriented Programming with Ansi-C de Axel-Tobias Schreiner.

Se define un struct base llamado Class. A partir de este se pueden crear más objetos que hereden los mismos atributos y métodos.

typedef struct {
    size_t size;
    void * (* ctor) (void * self, va_list * app);
    void * (* dtor) (void * self);
    void * (* clone) (const void * self);
    size_t (* sizeOf) (const void * self);
    int (* differ) (const void * self, const void * other);
    char * (* toString) (const void * self);
} Class;
/* Métodos sobrecargados: */
void * new(const void * _class, ...);
void delete(void * self);
void * clone(const void * self);
int differ(const void * self, const void * other);
size_t sizeOf(const void * self);
char * toString(const void * self);

Primero consideremos la forma habitual de inicializar una cadena:

#include <stdlib.h>

int main() {
    char * text = malloc(sizeof(char *) * 16);
    // char text[16];
    strcpy(text, "Hola mundo");
    printf("%s", text);
    return 0;
}

Aquí es necesario manejar la memoria de la cadena que vamos a utilizar. En caso de varias, el proceso sería más largo y su mantenimiento sería más difícil en caso de que el programa se haga más grande.

Mientras que utilizando la clase String:

#include "String.h"
#include <stdlib.h>

int main() {
    void * text = new(String, "Hola mundo");
    printf("%s", toString(text));
    return 0;
}

Ocultando el manejo de memoria en segundo plano.

Constructor

Para evitar esto último, se ha sobrecargado el método new() para inicializar cualquier objeto. En el caso de un String o cadena:

void * text = new(String, "Hello, world");

Esto no da paso a que el código adopte muchas formas distintas para crear una cadena/string. Además que hace más legible y agradable a la vista del programador. Sin embargo, es cierto que detrás de bambalinas es dónde opera la lógica y la gestión de memoria.

Clonador

En caso de necesitar una cadena con el mismo contenido de una pero sin apuntar a la misma dirección de memoria, se utliza:

void * textCopy = clone(text);
Destructor

En caso de ya no utilizar el String hacemos uso de la función delete(), que también hemos sobrecargado previamente:

delete(text);
toString

La función toString() retorna char * lo cual nos permite imprimir el contenido del objeto creado sin tener que acceder directamente a ese atributo delstruct.

printf("text = %s\n", toString(text));

Para compilar los ejemplos de uso y ver por consola el resultado, se puede utilizar el comando:

make examples && make run_examples

Todo el código figura en la carpeta examples.

Del mismo modo, para verificar la integridad de las funciones implementadas para cada clase, se puede utilizar el comando:

make tests && make check

Esto ejecutará un conjunto de tests escritos en C con la librería de acutest.h. De esta forma, también se pueden agregar más funcionalidades y testearlas.

Puedes eliminar todos los archivos compilados con el comando:

make clean

About

Objects in C: Strings, wchar_t, colors...

Topics

Resources

License

Stars

Watchers

Forks