Δημοσιεύτηκε: 23 Αύγ 2014, 00:00
από alkismavridis
Φυσικά! Σου παραθέτω μία κλάση που δεν επεκτείνει κάποια άλλη, για να επεκτείνεις η διαδικασία διαφέρει σε 1-2- σημεία.
Το βασικό που καταφέρνεις με την παρακάτω διαδικασία είναι ότι επιτρέπεις τον πολυμορφισμό. Δηλαδή όταν επεκτείνεις την κλάση αυτή, μπορείς να κάνεις override όποιες συναρτήσεις θες...

Μορφοποιημένος Κώδικας: Επιλογή όλων
//HEADER, Μπορεί να είναι σε ένα /h αρχείο.
#include <stdlib.h>
#include <stdio.h>
#define MyClass(X) (*(MyClass$**)(X))

typedef struct //static fields and method pointers
{
void (*myFunction)(void*);
}
MyClass$;

typedef struct
{
MyClass$* st;
int field;
}
MyClass;

void newMyClass$(MyClass$*); //Δηλώνουμε τους 2 constructor και τη μέθοδό μας
void* newMyClass(MyClass*, char);
static void myFunction(void*);


//Το .c αρχείο μας
//#include "MyClass.h"
static MyClass$ stat;

void newMyClass$(MyClass$* ptrs) //Ο constructor της κλάσης, χρειάζεται να καλεστεί μόνο μία φορά.
{
ptrs->myFunction = &myFunction;
}

void* newMyClass(MyClass* ptr, char old) //Ο constructor του instance, αρχικοποιεί ένα MyClass.
{
if (ptr==NULL) ptr = malloc(sizeof(MyClass)); //1. ο τυφλοσούρτης
if (!old)
{
if (*(char*)(&stat)==0) newMyClass$(&stat);
*(MyClass$**)ptr = &stat;
}

ptr->field=8; //2. η επεξεργασία των fields...
return ptr;
}

static void myFunction(void* th) //Η μέθοδός μας
{
MyClass* this = (MyClass*)th;
printf("Είναι ένα αντικείμενο MyClass. Η τιμή του field μου είναι %d.\n", (this->field));
}

void main()
{
MyClass* m = newMyClass(NULL,0);
MyClass(m)->myFunction(m);
m->field=3;
MyClass(m)->myFunction(m);
}


Επίσης! Για να διευκολυνθώ, έφτιαξα ένα πρόγραμμα που δημιουργεί αυτόματα ένα .c και ένα .h αρχείο, με τα "βασικά" κομμάτια κώδικα έτοιμα!
Μπορείς να κάνεις compile κατ' ευθείαν τα output αυτού του προγράμματος!
Το παραθέτω και αυτό
Μορφοποιημένος Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <string.h>

char *class, *super;

static void writeHFile(FILE* fl)
{
fprintf(fl, "#ifndef %s_h\n", class);
fprintf(fl, "#define %s_h\n\n", class);
if (super!=NULL) fprintf(fl, " #include \"%s.h\"\n", super);
else fprintf(fl, " #include <stdio.h>\n #include <stdlib.h>\n\n");

fprintf(fl, " #define %s(X) (*(%s$**)(X))\n\n typedef struct\n {\n", class, class);

if (super!=NULL) fprintf(fl, "\t%s$* super;\n", super);

fprintf(fl, "\t//new static data and methods...\n }\n");
fprintf(fl, "\t%s$;\n\n typedef struct\n {\n", class);

if (super!=NULL) fprintf(fl, "\t%s super;\n", super);
else fprintf(fl, "\t%s$* st;\n\n", class);

fprintf(fl, "\t//new fields go here...\n }\n");
fprintf(fl, "\t%s;\n\n", class);

fprintf(fl, " void new%s$(%s$*);\n", class, class);
fprintf(fl, " void* new%s(%s*, char /*more arguments*/);\n\n", class, class);
fprintf(fl, " //Other Methods go here...\n#endif");
}


static void writeCFile(FILE* fl)
{
fprintf(fl, "#include \"%s.h\"\n\n", class);
fprintf(fl, "static %s$ stat;\n\n", class);
fprintf(fl, "void new%s$(%s$* ptrs)\n{\n", class, class);

if (super!=NULL) fprintf(fl, "\tnew%s$((%s$*)ptrs);\n", super, super);
if (super!=NULL) fprintf(fl, "\t//To override: ((%s$*)ptrs)->method = &method;\n", super);

fprintf(fl, "\t//New method: ptrs->method = &method;\n}\n\n");
fprintf(fl, "void* new%s(%s* ptr, char old /*more arguments*/)\n{\n", class, class);
fprintf(fl, "\tif (ptr==NULL) ptr = malloc(sizeof(%s));\n\tif (!old)\n\t{\n", class);
fprintf(fl, "\t\tif (*(char*)(&stat)==0) new%s$(&stat);\n\t\t*(%s$**)ptr = &stat;\n\t}\n\n", class, class);

if (super!=NULL) fprintf(fl, "\tnew%s((%s*)ptr, 1 /*other arguments*/);\n\n", super, super);
fprintf(fl, "\t//field initialization goes here...\n");
fprintf(fl, "\treturn ptr;\n}\n\n");

fprintf(fl, "//Other methods go here...\n\n//void main() {}");
}


int main(int argc, char** argv)
{
char cfilename[50], hfilename[50];
FILE *fl;

if (argc==1) //1. Check if argument exists
{
printf("\nUsage:\n\tc_class_creator Classname\n\tc_class_creator Classname SuperClassName\n\n");
return 1;
}

class = argv[1];
if (argc>2) super=argv[2];
else super=NULL;

strcpy(cfilename, class);
strcat(cfilename, ".c");
strcpy(hfilename, class);
strcat(hfilename, ".h");

fl = fopen(cfilename, "r"); //2. See if files exist...
if (fl != NULL) { fclose(fl); printf("File %s already exists.\n", cfilename); return 1; }

fl = fopen(hfilename, "r");
if (fl != NULL) { fclose(fl); printf("File %s already exists.\n", hfilename); return 1; }

fl = fopen(cfilename, "w"); //3. Do the job!
writeCFile(fl);
fclose(fl);

fl = fopen(hfilename, "w");
writeHFile(fl);
fclose(fl);

return 0;
}


Χρήση: αν του δώσεις ένα όρισμα, φτιάχνει μία κλάση με αυτό το όνομα, η οποία δεν επεκτείνει καμία.
αν του δώσεις δύο ορίσματα φτιάχνει μία κλάση με όνομα το πρώτο, που επεκτείνει μία κλάση με όνομα το δεύτερο.