2009-09-17 3 views
0

Mon cours a ce membre.Std :: vector est initialisé à la poubelle. Comportement étrange. Des idées sur quoi?

std::vector<AvaWrapper> m_controls; 

Dans mon constructeur j'appelle

m_controls.clear() 

Puis j'appelle une fonction membre qui m_controls.clear fait() à nouveau, mais il souffle avec une assertion. Le débogueur montre que m_controls a un demi-million ou plus d'entrées, bien qu'aucune d'entre elles ne soit valide car le débogueur affiche "Erreur: l'expression ne peut pas être évaluée" lorsque je développe l'arborescence. Donc, mon intuition est que la classe n'est pas créée correctement parce que ce code a fonctionné mais j'ai ensuite dérivé une classe de cette classe et j'appelle new() pour créer le parent. Dans son nouveau rôle de classe de base, ça explose. Le pointeur this indique cependant que toutes les autres variables membres ont des données valides, donc mon intuition est fausse. Le constructeur est appelé aussi. Des idées? Merci.

MAJ2:

Train::Train() : SpriteWindowFrame(200) 
{ 
    s_mutexProtectingTheGlobalData = new wxMutex(); 
    m_window_rect = NULL; 
    m_thread = NULL; 
    m_ok = false; 
    m_accumulate_timer = new wxTimer(); 
    m_accumulate_timer->SetOwner(this, ACCUMULATE_TIMER_ID); 

    m_autohide_timer = new wxTimer(); 
    m_autohide_timer->SetOwner(this, AUTOHIDE_TIMER_ID); 

    m_autohide = false; 
    m_autohide_period = 5000; 
    m_controls.clear(); 
} 

MISE À JOUR:

//This version works. 
SpaceInit::SpaceInit() 
{ 
    //Use INI config store. If you need something else, just 
    //create the appropriate object. 
    m_config_store = new IniConfigStore(); 

    //Start up config. 
    Init(); 

    m_t = new Trains(); 
    return; 
} 

SpaceInit::~SpaceInit() 
{ 
    wxDELETE(m_config_store); 
    return; 
} 

Je peux le faire: m_t-> SomeMemberFunctionThatManipulatesVector()

et cela fonctionne.

Celui-ci ne

SpaceInit::SpaceInit():Trains() 
{ 
    //Use INI config store. If you need something else, just 
    //create the appropriate object. 
    m_config_store = new IniConfigStore(); 

    //Start up config. 
    Init(); 
    return; 
} 

Je ne peux pas faire: SomeMemberFunctionThatManipulatesVector()

souffle sur vecteur.

Je viens de remarquer que le pointeur this est vraiment foiré dans le consturctor par défaut de Train(). Je pensais que ce n'était pas mais ça l'est. Le constructeur Trains s'exécute mais tout est saccagé.

Le code du constructeur My Trains est géré par l'usine. Juste initialiser des choses, de nouvelles choses, etc. Le SpaceInit est créé avec SpaceInit * t = new SpaceInit(); Train est une classe dérivée alors peut-être que cela a quelque chose à voir avec ça?

+1

Pourriez-vous éventuellement nous donner le fichier d'en-tête et tout le code pertinent? – Smashery

+0

Quels sont les paramètres du template à std :: vector? Cela pourrait nous donner un indice –

+2

Vous devez d nous donner plus de code. Votre simplification ne suffit pas, et à cela, c'est faux. Vous ne pouvez pas avoir un membre 'std :: vector m_controls;' car ce n'est pas une utilisation valide de 'vector'. – GManNickG

Répondre

7

Il y a un problème avec cette déclaration:

I later derived a class from this class and I call new() to create the parent.

Lorsque vous dérivez d'une classe, vous n'appelez pas nouvelle() pour créer un parent. Le constructeur parent est déjà appelé avant l'exécution de la première ligne du constructeur enfant.

Je suppose que votre problème pourrait être autour de cette zone. Peut-être pourriez-vous nous montrer le code où cela se passe.

+1

+1 pour moi pour avoir donné un premier diagnostic sans crier "CODE GIEV!". En particulier, le commentaire «donnez-moi tous les codes pertinents» à la question est inutile puisque le créateur de la question ne sait probablement pas ce qui est pertinent et ce qui ne l'est pas. –

1

Puisque vous semblez avoir des pointeurs RAW (difficile à dire car nous n'avons pas la définition de SpaceInit). Avez-vous défini le constructeur de copie et l'opérateur d'affectation. Si ce n'est pas le cas, vous pourriez éventuellement accéder à des objets détruits ce qui conduirait à un comportement indéfini inclus écraser les autres membres.

+0

Non. Je n'ai pas beaucoup d'expérience de surcharge de ces opérateurs. Pourquoi cela serait-il nécessaire? Je ne clone pas ou ne copie pas les objets. – max

+0

Il y a beaucoup d'opérations qui provoquent la copie d'objets qui ne sont pas évidents. Si vous êtes sûr qu'ils ne sont pas copiés, définissez les opérateurs de copie/affectation comme privés et vérifiez si le code est toujours compilé. Si c'est le cas, vous êtes en sécurité sinon vous avez un problème. –

1

Je suis avec @ andrew-shepherd. Comme vous avez obtenu des résultats différents lorsque vous avez modifié l'ordre d'initialisation des trains de la classe, je vous recommande fortement de vérifier toutes les classes de base et dérivées concernant la liste d'initialisation."

Si vous n'êtes pas autorisé à afficher l'extrait de code spécifique, s'il vous plaît au moins assurer que tous les membres de données de chaque classe étaient sur la liste d'initialisation, pas dans le cteur.

+0

oh, ils sont dans le constructeur. Les déplacer vers la liste d'initialisation ferait-il une différence? – max

+0

En C++ c'est toujours une meilleure idée d'utiliser la liste d'initialisation, une partie de la raison a été donnée par @dominolog. Puisque vous avez un comportement différent sur les différents ordres new() de la classe dérivée, en particulier autour de IniConfigStore et Init(), dont nous ne savons pas ce qu'il a fait ici, cela vaut la peine de vérifier toute la progression de l'initialisation. L'utilisation de la liste d'initialisation est l'un des moyens les plus faciles de les protéger. – Barabbas

0

Je suis juste geuessing que le Init méthode est virtuelle. la règle no. 1 est vous n'appeler des méthodes virtuelles à partir cteur parce que l'objet ne peut pas être initialisé correctement.

Cordialement