Witam.
Nie znalazłem w internecie podobnego przykładu więc piszę tutaj.
Piszę symulator układów logicznych z pomocą Allegro5 w VC++ 2010 Express i w funkcji rysującej chciałbym wywołać funkcję rysującą każdej bramki logicznej z osobna a więc zrobiłem tak (w prawie pseudokodzie)
class Element
{
protected:
int x, y;
bool state;
public:
virtual void draw() { }
virtual void setInput( Element * ) { }
virtual void clearInput() { }
virtual void updateInput() { }
virtual void updateState() { }
virtual void changeState() { }
bool getState() { return state; }
};
class BramkaNOT
: public Element
{
protected:
Element * input;
public:
virtual void draw();
};
void draw()
{
rysuj( x, y );
}
int main()
{
Element * element[ ILOSC_ELEMENTOW ];
for( int i = 0; i < ILOSC_ELEMENTOW; ++i )
{
element[ i ] = NULL;
}
while( true )
{
if( klikniecieMysza && wybranyElement == NOT )
{
for( int i = 0; i < ILOSC_ELEMENTOW; ++i )
{
if( element[ i ] == NULL )
{
element[ i ] = new BramkaNOT( myszX, myszY );
}
break;
}
}
for( int i = 0; i < ILOSC_ELEMENTOW; ++i )
{
if( element[ i ] )
{
element[ i ]->draw();
}
}
}
I jeśli nie tworzyłbym nadrzędnej klasy Element to musiałbym dla każdego obiektu tworzyć tablice i kombinacji w tym sporo by było. Ale tworząc klasę Element z tymi wszystkimi metodami wirtualnymi robię trochę bałaganu i często wywołuje puste funkcje (myślę że to spowalnia program).
Także pobierając dane z input-u muszę deklarować wskaźnik na obiekt typu element.
Jednakże tworząc po kilka różnych wskaźników (np. po 2 dla jednego rodzaju bramki) zajmę kupę pamięci przy 2000 bramek.
Więc kombinowałem i wpadłem na rozwiązanie:
union Element
{
BramkaNOT * NOT;
BramkaAND * AND;
}
Wówczas mogę tworzyć tablicę wskaźników której przyporządkuje dowolny obiekt, a zajmuje pamięci tyle co ilość wskaźników.
Te obiekty nie muszą być nawet powiązane ze sobą.
Ustaliłem że liczy się kolejność metod w klasie np.
class BramkaNOT
{
protected:
bool state;
Element * input;
public:
void draw();
void getState() { return state; }
};
class BramkaAND
{
protected:
bool state;
Element * input1;
Element * input2;
public:
void getState() { return state; }
void draw();
};
Element * element = new Element;
Element->NOT = new BramkaNOT;
Element->NOT->draw();
Element->AND->draw();
Tutaj funkcję wywołuje już dowolnym typem wskaźnika
Czy takie rozwiązanie jest poprawne, czy pierwsze lepsze?
P.S. Uważam to na razie za ciekawostkę, ale może się jednak przydać
P.S.2 Niektóre bramki mogą dziedziczyć po np. bramka_dwuargumentowa itp. Rozważałem też klasy nadrzędne, Drawable itp.
EDIT:
Przy dziedziczeniu z klas typu Drawable, kolejność funkcji (w tym wypadku draw()) nie ma znaczenie, i nie w pływa na numery funkcji niedziedziczonych.