domenica, maggio 03, 2009

Disegno? Una questione di allenamento!

Saper disegnare sicuramente richiede capacità e talento.. io non penso di averli, però ho scoperto l'acqua calda: le capacità si costruiscono con l'allenamento, il talento può essere innato.. ma può anche essere costruito con l'esperienza.
Non ci credete? Bé non sono mai stato bravo a disegnare, nonostante io scolpissi e dipingessi con l'areografo (e qualche volta sulle magliette)...

E ADESSO???

Non so disegnare nemmeno ora, però comincio a stendere la grafite sulla carta in maniera quasi accettabile per un principiante. Un esempio? Eccolo:

mercoledì, marzo 04, 2009

E se dovessi programmare in C ANSI.. ma OO?

Oramai é sempre più raro trovarsi in questa situazione esistendo svariate soluzioni sia open che commerciali per lo sviluppo e la compilazione di codice C++ anche per architetture embedded. Ogni tanto però capita ancora di avere questa esigenza.. in quei casi?

La risposta viene da molto lontano nel tempo, molti di voi avranno sentito parlare del documento OOC, in cui si descrivono le tecniche per programmare in uno stile OO utilizzando l'ANSI C. Questo documento esiste da molti anni.. e quando lo scoprii (nel 2002 se non ricordo male) mi entusiasmò! In questi giorni però la stessa domanda mi é stata riproposta da un curioso molto in gamba.. e perché non fornirla a tutti sul blog? Ma di più.. dato che non ho mai nulla da fare (ironico ovviamente), perché non scrivere un esempio semplice semplice di tool costruito con le macro di preprocessore? E' un giocattolino senza esplicito supporto per l'ereditarietà, il polimorfismo e quant'altro.. però é simpatico e chi vuole può usarlo/estenderlo per gioco. Eccovelo in sole 50 righe di macro con un esempio semplice semplice.

Vediamo un esempio di dichiarazione di classe:

// La classe:
CLASS_BEGIN(CheckedInt)
ATTRIBUTE(CheckedInt,int,version);
METHOD(CheckedInt,void,setValue,unsigned long val);
METHOD(CheckedInt,unsigned long,getValue);
STATIC_METHOD(CheckedInt,unsigned long,max_val);
CLASS_END(CheckedInt)

// La struttura rappresentante un'istanza:
CLASS_INSTANCE_BEGIN(CheckedInt)
ATTRIBUTE(CheckedInt,unsigned long,value);
ATTRIBUTE(CheckedInt,unsigned long,not_value);
CLASS_INSTANCE_END(CheckedInt)

// Definizione di costruttore e distruttore:
CLASS_ALLOCATORS(CheckedInt,unsigned long val);
Lineare no? E l'implementazione? Eccola:

// Metodo d'istanza:
METHOD_IMPL_BEGIN(CheckedInt,void,setValue,unsigned long val)
this->value = val;
this->not_value = ~val;
METHOD_IMPL_END(CheckedInt)

// Caso statico:
STATIC_METHOD_IMPL_BEGIN(CheckedInt,unsigned long,max_val)
return 0xFFFFFFFE;
STATIC_METHOD_IMPL_END(CheckedInt)

//...

// Inizializzazione della struttura statica:
CLASS_INIT( CheckedInt,1,
CheckedInt_setValue,
CheckedInt_getValue,
CheckedInt_max_val);

// Costruttore:
CONSTRUCTOR_BEGIN(CheckedInt,unsigned long val)
this->value = val;
this->not_value = ~val;
CONSTRUCTOR_END(CheckedInt)

// Distruttore:
DESTRUCTOR_BEGIN(CheckedInt)
// Rilascio risorse.
DESTRUCTOR_END(CheckedInt)
Usiamo la nostra classe ora!

// Istanzio:
CheckedInt *ckdInt = CheckedInt_new(10);

// Chiamo un po:
printf("A checked value: %d\n", CALL(ckdInt,getValue));
CALL(ckdInt,setValue,42);
printf("A checked value: %d\n", CALL(ckdInt,getValue));

// Accedo agli attributi direttamente:
printf("I'm a bad boy! ;)\n");
ckdInt->not_value = 0;
printf("A checked value: %d\n", CALL(ckdInt,getValue));

// Uso il distruttore:
CheckedInt_free(ckdInt);
Ok, probabilmente molti di voi diranno "Tra C++, Java, C#, cicici e tututu sicuramente questo non mi serve!", sono perfettamente d'accordo con voi... ma ogni sfizio è sfizio!!! ;)