2010-10-27 4 views
0

Je rencontre un problème avec l'appel d'une méthode avec l-valeur d'une classe abstraite. La définition de la classe est:en utilisant l-valeur avec la classe abstraite

class SimulatorSequenceItemBase { 
public: 
    SimulatorSequenceItemBase(); 
    virtual ~SimulatorSequenceItemBase(); 

    virtual uint32_t GetResult(uint32_t p_nSite) = 0; 
    virtual bool MoveNext(SimulatorSequenceItemBase& p_rNext) = 0; 
} 

SimulatorSequenceItemBase a plusieurs sous-classes. Il y a des séquences (pour les boucles) et des éléments pour la boucle for.

Je veux faire une boucle dans la séquence et compter les étapes, en utilisant:

uint32_t nI = 0; 
SimulatorSequenceItemBase root = forSeq; // forSeq is an instance of a subclass of SimulatorSequenceItemBase 
while(root.MoveNext(root)) 
{ 
    ++nI; 
    std::cout << root.GetResult(0); 
} 

La racine Initally références à la racine, et chaque appel à MoveNext, la référence doit être ajustée à l'élément suivant.

Le code mentionné ci-dessus ne fonctionne pas, car la racine ne peut pas être allouée, car le type de racine est abstrait. Mais si je devais créer un pointeur, la valeur ne peut pas être modifiée dans MoveNext.

Comment puis-je résoudre ce problème? C'est bien de changer n'importe quel code, mais l'idée devrait rester la même.

+2

Je me demande qui 'nI' est –

+1

@Armen: C'est le pseudo secret de Nicolai Josuttis. ':)' – sbi

Répondre

2

Je ne sais pas ce que forSeq est censé être, mais ce qui ne va pas avec

SimulatorSequenceItemBase& root = forSeq; // note that & 

Depuis, selon un commentaire, vous devez réinitialiser root pour faire référence à des objets différents, vous devrez utiliser des pointeurs :

SimulatorSequenceItemBase* root = forSeq; note the * 
while(root.MoveNext(root)) 
{ 
    // ... 
} 

Cependant, afin d'avoir MoveNext() remis à zéro root, il doit prendre le pointeur par référence:

bool MoveNext(SimulatorSequenceItemBase*& p_rNext) // note the *& 
+0

selon la littérature: "Une fois initialisée, la réfrence elle-même ne peut être faite pour se référer à autre chose." (C++ Pocked référence - Kyle Loudon - O'Reilly), ce qui signifie que cela ne fonctionnerait pas pour moi, car je veux reporter la racine à divers éléments sur l'itération. – Excel20

+0

@ Excel20: Votre code n'a pas montré que vous vouliez 'root' pour faire référence à différents objets. Si vous devez le faire, vous devrez utiliser un pointeur. Je vais modifier ma réponse. – sbi

0

OK, tout d'abord. Pourquoi MoveNext prend-il un argument? Ça ne devrait pas.

virtual bool MoveNext() = 0; 

puis

SimulatorSequenceItemBase& root = forSeq; 
while(root.MoveNext()) 
{ 
    ++nI; 
} 
1

La raison pour laquelle vous avez un problème est parce que la ligne SimulatorSequenceItemBase root = forSeq; est en fait de créer une nouvelle instance de SimulatorSequenceItemBase sur la pile (une copie épissée de forSeq). Parce que vous avez une fonction virtuelle pure, vous ne pouvez pas créer une instance de la classe de base. Ce que vous devez faire est de changer d'utiliser une référence ou un pointeur:

SimulatorSequenceItemBase *pRoot = &forSeq; 

while (pRoot->MoveNext(pRoot)) 
{ 
    ++nI; 
    std::cout << pRoot->GetResult(0); 
} 

Modifier Suite à votre commentaire, je suggère refactoring votre code pour être quelque chose comme ceci:

SimulatorSequenceItemBase *pNode = &forSeq; 
while (pNode != NULL) 
{ 
    ++nI; 
    std::cout << pRoot->GetResult(0); 

    pNode = pNode->MoveNext(); 
}; 
+0

selon la littérature: "Une fois initialisée, la référence elle-même ne peut être faite pour se référer à autre chose." (C++ Pocked référence - Kyle Loudon - O'Reilly), ce qui signifie que cela ne fonctionnerait pas pour moi, car je veux référencer la racine à divers éléments sur l'itération. – Excel20

+0

Dans ce cas, utilisez un pointeur, car ils peuvent se référer à d'autres variables après (j'ai mis à jour ma réponse). –

+0

Si vous laissez le paramètre, vous affecteriez le pointeur de l'élément suivant à 'this'? – Excel20

Questions connexes