2013-01-02 2 views
0

Mon problème est que j'ai une base et 3 classes d'enfants et je voulais faire un vecteur où je peux placer tous les éléments qui sont des représentants de l'ensemble des 3 classes d'enfants. Voici la partie du code qui gèrent de depuis un fichierC++ lecture dans un fichier à vecteur de pointeurs

vector<Robot*> robots; 
vector<Mac> mac; 
vector<Eco> eco; 
vector<Pro> pro; 
vector<int> charge; 
vector<int> deliver; 

try { 
    string s; 
    ifstream f; 

    do { 
     cout << "Add meg a filenevet" << endl; 
     cin >> s; 
     f.open(s.c_str()); 
    } while (!f.good()); 

    cout << "adatok beolvasasa..." << endl; 

    int napok; 
    if (!(f >> napok)) throw 1; 
    charge.resize(napok); 
    deliver.resize(napok); 

    for (int i = 0; i<napok; i++) { 
     if (!(f>>charge[i])) throw 1; 
     if (!(f>>deliver[i])) throw 1; 
    } 

    string type, name; 
    int battery; 
    int m = 0; int e = 0; int p = 0; 
    std::string line; 
    while (std::getline(f, line)) { 
     stringstream ss(line); 
     if (ss >> type && ss >> name && ss >> battery) { 

      if (type=="Mac") { 
       cout << "mac" << endl; 
       Mac r = Mac(name,battery); 
       mac.push_back(r); 
       robots.push_back(&mac[m]); 
       m++; 
      }; 
      if (type=="Eco") { 
       cout << "eco" << endl; 
       Eco r = Eco(name,battery); 
       eco.push_back(r); 
       robots.push_back(&eco[e]); 
       e++; 
      } 
      if (type=="Pro") { 
       cout << "pro" << endl; 
       Pro r = Pro(name,battery); 
       pro.push_back(r); 
       robots.push_back(&pro[p]); 
       p++; 
      }; 
     } 
    } 

Cela fonctionne jusqu'à présent, il compile et fonctionne aussi bien, mais lorsque je tente d'accéder à une fonction ex robots[i].getBattery(); le gel du programme. il semble que les pointeurs pointent juste dans nulle part, mais je ne sais pas pourquoi :(

+0

Où est vous appelez à 'robots [i] .getBattery();'? Si 'mac',' eco' et 'pro' sont détruits, leurs membres le sont aussi. Cela conduit à des «robots» contenant des pointeurs vers des objets invalides. – Oswald

+0

Ils ne sont pas détruits:/ive écrit tout cela dans la fonction principale (en espérant que cela rendra un peu plus facile) et je l'appelle dans la fonction principale aussi. – Andesz

Répondre

1

Le problème est que vous avez deux façons indépendants d'accéder à vos objets sans synchronisation entre les deux.

Si vous appuyez sur une Dans un vecteur, puis pointez dessus, le pointeur n'est valide que si le stockage du vecteur n'est pas déplacé ou invalidé Dans votre cas, les appels répétés de push_back() peuvent bien déclencher une réallocation vectorielle et cela n'est pas garanti que cela peut se produire en place, de sorte que les éléments peuvent se déplacer dans un nouvel emplacement de mémoire, mais évidemment, les pointeurs ne sont pas mis à jour. par conséquent, vous vous retrouvez avec des pointeurs vers nulle part.

Disposer d'un ensemble de conteneurs pour contenir les données et d'un autre conteneur contenant uniquement des pointeurs vers ces données me semble plutôt mauvais. Comme je le vois, vous avez deux options pour améliorer le code et résoudre les problèmes que vous rencontrez. Dans les deux cas, il vous suffit d'un conteneur pour contenir des pointeurs vers les éléments polymorphes, il est juste la façon que vous déclarez les conteneurs:

1) Utilisez un boost::ptr_vector pour stocker les pointeurs à vos objets polymorphes. Ce conteneur est conçu pour contenir des pointeurs (qu'un std::vector ne l'est pas, ce dernier a une valeur sémantique) et prend en charge la gestion à vie des objets qu'il contient.

2) Si vous ne pouvez pas utiliser boost, utilisez un std::vector<std::shared_ptr<Robot> > pour contenir les pointeurs vers les objets polymorphes.

Dans les deux cas, vous en finir avec les conteneurs qui contiennent des éléments en valeur et dans votre instruction if, vous allouez les objets sur le tas, puis mettez les pointeurs dans le récipient.

Questions connexes