2010-08-11 2 views
2

Les classes Button, TextBox et CheckBox sont des wrappers maison de CreateWindowEx. C++/STL - Le programme plante en accédant à une instance de pointeur de classe dans un std :: map

std::map<const char*, Button*> Buttons; 
std::map<const char*, TextBox*> TextBoxes; 
std::map<const char*, CheckBox*> CheckBoxes; 

Voici la fonction qui renseigne les cartes:

void Window::LoadFromXml(const char* fileName) 
{ 
    XMLNode root = XMLNode::openFileHelper(fileName, "Window"); 

    for(int i = 0; i < root.nChildNode("Button"); i++) 
    {   
     Buttons.insert(std::pair<const char*, Button*>(root.getChildNode("Button", i).getAttribute("Name"), new Button)); 
     Buttons[root.getChildNode("Button", i).getAttribute("Name")]->Init(_handle); 
    } 

    for(int i = 0; i < root.nChildNode("CheckBox"); i++) 
    {  
     CheckBoxes.insert(std::pair<const char*, CheckBox*>(root.getChildNode("Button", i).getAttribute("CheckBox"), new CheckBox)); 
     CheckBoxes[root.getChildNode("CheckBox", i).getAttribute("Name")]->Init(_handle); 
    } 

    for(int i = 0; i < root.nChildNode("TextBox"); i++) 
    {    
     TextBoxes.insert(std::pair<const char*, TextBox*>(root.getChildNode("TextBox", i).getAttribute("Name"), new TextBox)); 
     TextBoxes[root.getChildNode("TextBox", i).getAttribute("Name")]->Init(_handle); 
    } 
} 

Voici le fichier xml:

<Window> 
    <TextBox Name="Email" /> 
    <TextBox Name="Password" /> 

    <CheckBox Name="SaveEmail" /> 
    <CheckBox Name="SavePassword" /> 

    <Button Name="Login" /> 
</Window> 

Le problème est, si j'essaie d'accéder, par exemple, TextBoxes["Email"]->Width(10);, le programme compile bien, mais se bloque quand je le lance.

Je l'appeler d'une classe dérivée:

class LoginWindow : public Window 
{ 
public: 

    bool OnInit(void) // This function is called by Window after CreateWindowEx and a hwnd == NULL check 
    { 
     this->LoadFromXml("xml\\LoginWindow.xml"); // the file path is right 
     this->TextBoxes["Email"]->Width(10); // Crash, if I remove this it works and all the controls are there 
    } 
} 

Répondre

5

Le problème est probable que votre carte a const char* en tant que clés - et cela ne signifie pas que les chaînes, mais des pointeurs. Ce qui signifie qu'il voit deux pointeurs différents sur les mêmes chaînes (par exemple, votre chaîne littérale "Email" et caractères "Email" que vous avez lu dans le fichier) comme différent, donc il ne trouve pas le pointeur sur la zone de texte " crash "line (et exécute une méthode d'un objet inexistant à la place). Je vous suggère de changer les types de cartes en std::map<std::string, ...>. À part cela, je vous suggère d'utiliser std::make_pair(a, b) au lieu de spécifier manuellement le type de la structure de paire.

+0

merci, jpalecek, btw, était-ce une question débutant, intermidiate ou avancée? – Martin

3

quoi faire des choses comme root.getChildNode("Button", i).getAttribute("CheckBox") retour? c'est clairement un char* (peut-être const), mais où est-il alloué? Tas? Si oui, quand le libérez-vous?

Il est possible selon l'API de retourner un tampon statique ou autre chose qui ne dure pas aussi longtemps que votre map, ce qui pourrait provoquer des plantages et autres comportements funky. Vous devez faire vos map s ressembler à ceci et ne pas avoir à vous soucier de:

std::map<std::string, Button*> Buttons; 
std::map<std::string, TextBox*> TextBoxes; 
std::map<std::string, CheckBox*> CheckBoxes; 
Questions connexes