2010-11-24 15 views
1

Bonjour les gens, Je suis coincé avec un problème C++ stupide.Problème avec std :: vector

Disons que j'ai un itérateur appelé IT1 qui passe par les valeurs d'un vecteur contenant des pointeurs à une classe, nous l'appellerons C:

std::vector<C*>::iterator it1; 

Mais C est pas seul: il a beaucoup de sous-classes , qui partagent les mêmes attributs et méthodes que je cherche avec it1, bien que leurs implémentations puissent différer ou non. Que devrais-je faire si je voulais que l'itérateur fonctionne avec des éléments (ou mieux, des pointeurs) non seulement de la classe C, mais aussi de ses enfants? Ce que je pensais être quelque chose en utilisant des modèles, bien que cela rendrait les itérations dangereuses car je ne sais pas comment limiter le modèle uniquement à C et ses sous-classes. Aucune suggestion?

Editer: oui, je parlais d'une structure de données récursive. Edit2: Eh bien, il semble que ce n'était pas la faute de l'itérateur après tout. Mon code fonctionnait bien, j'ai posé la question parce que j'allais mettre en œuvre des changements et je ne savais pas quoi faire. Désolé si ce n'était pas clair.

+0

Parlez-vous d'une structure de données récursive ou plate? Vous utilisez des termes qui rendent la distinction confuse. – robert

+1

Il est déjà limité à C et à ses enfants. –

+0

votre code devrait fonctionner. Pouvez-vous montrer plus de fragment de code que non? –

Répondre

2

Je pense que je sais ce que vous voulez dire. C est votre classe de base et, disons A et B dérivent de C. Mais il y a des fonctions A et/ou B qui ne sont pas là en C, c'est ça que vous voulez dire? Dans ce cas, vous devrez baisser *it à A* ou B*. Si cela doit être fait dans des cas exceptionnels, alors OK, sinon vous devriez revoir ...

+0

Oui, exactement. Je dois le faire juste une fois mais c'est un mauvais design, tu as raison. – Hector

1

Un vecteur < C *> :: itérateur fonctionne uniquement avec un vecteur < C *>. Quelqu'un peut faire d'autres itérateurs, mais ils ne fonctionneront pas avec votre structure. Et sur la base polymorphisme, un vecteur < C *> :: iterator peut "point" à une sous-classe de C.

2

Cela fonctionne très bien:

class C 
{ 
    public: 
     virtual void WhoAmI() { std::cout << "C\n"; } 
}; 
class D: public C 
{ 
    public: 
     virtual void WhoAmI() { std::cout << "D\n"; } 
}; 

int main() 
{ 
    C     cObject; 
    D     dObject; 
    std::vector<C*> data; 
    data.push_back(&cObject); 
    data.push_back(&dObject); 

    std::vector<C*>::iterator it1; 

    for(it1 = data.begin(); it1 != data.end(); ++it1) 
    { 
     (*it1)->WhoAmI(); 
    } 
} 
1

Tant que vous n'appelez que des méthodes (virtuelles) définies dans l'interface publique de la classe C, alors l'héritage et la liaison dynamique prendront prendre soin de tout pour vous. Donc, si vous avez, par exemple

class C { 
public: 
    virtual oid doit() { std::cout << "I am a C object" << std::endl; } 
}; 

class D : public C { 
public: 
    void doit() { std::cout << "I am a D object" << std::endl; } 
}; 

int main() 
{ 
    C c; 
    D d; 
    std::vector<C*> cs; 
    cs.push_back(&c); 
    cs.push_back(&d); 

    vector<C*>::iterator ci; 
    for (ci = cs.begin(); ci != cs.end(); ci++) { 
     (*ci)->doit(); 
    } 
} 

Le iterator accède à chaque pointeur, puis appelle la fonction Doït() sur chaque objet accessible via le pointeur - mais la liaison dynamique entre en jeu pour décider quelle version de l'obole() La fonction est appelée en fonction du type d'exécution de l'objet.