Ik probeer in C++ iets te doen met lijsten van verschillende objecten, maar heb wat probleempjes met het accessen van afgeleide classes. Meer concreet, ik heb de volgende base class:
En een aantal afgeleide classes, bijvoorbeeld rrSquare:
Nu wil ik een lijst implementeren die allerlei verschillende objecten kan bevatten (squares, triangles, spheres, etc). Dit heb gedaan als volgt:
Tot zover gaat het goed. Ik kan met addObject(..) ook netjes bijvorrbeeld een rrSquare object in de lijst gooien. Het probleem is echter dat ik daarna de data van de afgeleide classes niet meer terug kan vinden.
Ik wil ergens anders bijvoorbeeld het volgende doen:
drawSquare verwacht een rrSquare object, dus dit werkt niet. Ik heb het toen gewijzigd in:
... dit is compileerbaar, maar als ik nu bijvooreeld square.getSize() doe in die drawSquare(rrSquare square) { .. } method, dan levert ie altijd 0 op, ongeacht waar ik de size op het ingesteld. Ik kan de data uit de base class echter nog wel benaderen; als ik bijvoorbeeld square.getObjectType(); doe komt er netjes 10 uit (en dit klopt -- zie #def).
Ik heb het eea gelezen over polymorfisme, maar ik denk niet dat dat hier echt van toepassing is, aangezien ik niet 1 en dezelfde functie voor verschillende objecten wil definieren. Een rrSquare heeft bijvoorbeeld een size, maar een rrSphere heeft dit niet (maar een radius), etc, dus de objecten zullen ook verschillende methods bezitten (getSize, getRadius, etc).
Ik vraag me nu twee dingen af:
1. Bezit de lijst zoals ik die nu heb geimplementeerd alleen info over de base classes, of ook wel degelijk over de afgeleide classes?
2. Indien het tweede, dan lijkt het me dat ik die informatie op de eoa manier ook weer moet kunnen accessen; maar bovenstaande casting-methode lijkt dus niet te werken
Waarom niet? En hoe moet het dan wel?
Ik herinner met dat ik iets dergelijks ook ooit in Java heb gedaan en daar was het volgens mij niet zo'n probleem...
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| #define SQUARE 10
//etc
class rrObject {
protected:
rrVector color; // color of the 2D object
bool visibility; // true if visible
int objectType; // type of object (SQUARE, RECTANGLE or TRIANGLE)
// etc
public:
void setVisibility (bool vis);
bool getVisibility ();
short getObjectType ();
// etc
}; |
En een aantal afgeleide classes, bijvoorbeeld rrSquare:
code:
1
2
3
4
5
6
7
8
9
10
11
12
| class rrSquare: public rrObject {
private:
rrVector position; // position of the left-top corner
double size; // size
public:
rrSquare();
rrSquare(rrVector pos, rrVector norm, int s, rrVector col, bool vis);
void setSize(double s);
double getSize();
// etc
}; |
Nu wil ik een lijst implementeren die allerlei verschillende objecten kan bevatten (squares, triangles, spheres, etc). Dit heb gedaan als volgt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| class rrObjectGroup {
public:
rrObject object[MAX_OBJECTS]; // list of 2D en 3D objects
int count; // number of objects in list
// constructors
rrObjectGroup ();
// object manipulators
void addObject (rrObject obj); // add an rrLightNode
void removeObject (int num); // remove an rrLightNode
int getCount(); // return count
}; |
Tot zover gaat het goed. Ik kan met addObject(..) ook netjes bijvorrbeeld een rrSquare object in de lijst gooien. Het probleem is echter dat ik daarna de data van de afgeleide classes niet meer terug kan vinden.
Ik wil ergens anders bijvoorbeeld het volgende doen:
code:
1
| drawSquare(objectGroup.object[i]); |
drawSquare verwacht een rrSquare object, dus dit werkt niet. Ik heb het toen gewijzigd in:
code:
1
| drawSquare((rrSquare*) &objectGroup.object[i]); |
... dit is compileerbaar, maar als ik nu bijvooreeld square.getSize() doe in die drawSquare(rrSquare square) { .. } method, dan levert ie altijd 0 op, ongeacht waar ik de size op het ingesteld. Ik kan de data uit de base class echter nog wel benaderen; als ik bijvoorbeeld square.getObjectType(); doe komt er netjes 10 uit (en dit klopt -- zie #def).
Ik heb het eea gelezen over polymorfisme, maar ik denk niet dat dat hier echt van toepassing is, aangezien ik niet 1 en dezelfde functie voor verschillende objecten wil definieren. Een rrSquare heeft bijvoorbeeld een size, maar een rrSphere heeft dit niet (maar een radius), etc, dus de objecten zullen ook verschillende methods bezitten (getSize, getRadius, etc).
Ik vraag me nu twee dingen af:
1. Bezit de lijst zoals ik die nu heb geimplementeerd alleen info over de base classes, of ook wel degelijk over de afgeleide classes?
2. Indien het tweede, dan lijkt het me dat ik die informatie op de eoa manier ook weer moet kunnen accessen; maar bovenstaande casting-methode lijkt dus niet te werken
Ik herinner met dat ik iets dergelijks ook ooit in Java heb gedaan en daar was het volgens mij niet zo'n probleem...