J'ai une classe de jetons qui ressemble à ceci :
class Token
{
public:
typedef enum { STRTOK, INTTOK } Type;
virtual bool IsA(Type) = 0;
}
class IntTok : public Token
{
int data;
public:
bool IsA(Type t) { return (t == INTTOK); }
int GetData() { return data; }
}
IntTok newToken;
if ( newToken.IsA(Token::INTTOK )
{
//blah blah
}
Je dois donc définir chaque sous-classe dans la classe Token, ce qui n'est pas si mal car il y a très peu de sous-classes et je ne peux pas imaginer qu'elles changent. Mais c'est quand même moche, maladroit et moins "correct" que d'identifier les sous-classes à l'aide d'un cast dynamique. Cependant :
IntTok newToken;
IntTok* tmpTokenTest = dynamic_cast<IntTok*>(&newToken);
if ( tmpTokenTest != NULL )
{
//blah blah
}
Est également assez peu pratique. En particulier lorsque je dois les enchaîner dans un grand "if" imbriqué.
Alors, lequel choisiriez-vous ? Existe-t-il une autre solution à ce problème ?
Remarque : Je sais que je devrai de toute façon les lancer pour obtenir leurs données respectives, mais
- Je ne les lancerai que juste avant d'utiliser leur fonction, ce qui me semble plus propre et plus efficace.
- Je teste leur type bien plus souvent que je n'utilise leurs données.
Note2 : Le code ci-dessus n'indique pas que ces jetons sont également une liste chaînée. Cela rend le templating difficile (un Token<int>
peut pointer vers un Token<string>
etc). C'est pourquoi j'ai besoin d'une classe Token comme parent pour commencer.