IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Threads & Processus C++ Discussion :

2 pb differents : IHM dans thread secondaire et cast en classe heritee


Sujet :

Threads & Processus C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 10
    Points : 2
    Points
    2
    Par défaut 2 pb differents : IHM dans thread secondaire et cast en classe heritee
    bonjour à tous,

    Voilà, j'ai deux problèmes :

    1/
    Pour une application, utilisant visual2008 et les MFC, je crée un thread dans lequel je crée mon IHM principale (create (IDD...) puis ShowWindow()).
    A la sélection d'un item du menu de l'IHM principale, je souhaite crée une boite de dialogue modale dont l'IDD est attaché à une classe.

    Au final, à l'affichage de la deuxieme boite de dialogue, il n'est plus possible de cliquer, ni sur l'une ni sur l'autre, comme si elles etaient occupées. En mode debug, je m'apperçois que le code est bien dans le peekMessage de la fonction DoModal(). Y aurait-il un conflit quelque part?

    Pour illuster voici les parties du code :

    Code procedure du thread secondaire : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // Creation de l'IHM principale // 
    CIhmPrincipal main_ihm ; 
     
    //affichage de l'IHM principale 
    main_ihm.StartIhm(); 
    ...
    //peekmessage() pour ecouter les autres threads

    Code dans le constructeur de la classe de l'IHM principale : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    AfxGetApp()->m_pMainWnd = this; 
    this->Create(IDD_IHM_PRINCIPAL); 
     
    Fonction StartIhm() : 
    ... 
    this->ShowWindow(SW_SHOWMAXIMIZED);

    Code Dans la fonction appelée à la selection de l'item du menu : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int result = 0; 
    this->SetForegroundWindow(); 
    m_pcIhmSecond = new CIhmSecond(this); 
    result = m_pcIhmSecond->DoModal();
    2/
    Dans cette même appli, je partage une Queue entre differents threads :
    queue<ClasseMere> g_queue

    dans un thread, je remplie cette queue avec des objets de classe derivée à ClasseMere :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ClasseFille1 obj1;
    g_queue.push(obj1);
    ClasseFille2 obj2;
    g_queue.push(obj2);
    Dans un autre thread, je lis le contenu de g_queue et je veux faire un traitement different selon que l'objet situé en tête de g_queue soit de la classe ClasseFille1 ou de la classe ClasseFill2

    => comment faire puisque g_queue.front() retourne un objet de la classe ClasseMere???



    Merci d'avance pour votre aide

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Tu ne dois pas utiliser le polymorphisme avec des conteneurs qui stockent par valeur : Il te faut stocker des pointeurs dans tes conteneurs.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Salut,

    Citation Envoyé par cyrmaril Voir le message
    je lis le contenu de g_queue et je veux faire un traitement different selon que l'objet situé en tête de g_queue soit de la classe ClasseFille1 ou de la classe ClasseFill2

    => comment faire puisque g_queue.front() retourne un objet de la classe ClasseMere???
    En délégant aux classes filles le traitement en question.

    Au passage, puisque plusieurs threads y accèdent, est-ce que tu protèges l'accès à la std::queue ?

    MAT.

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    c'est-à-dire que dans mon premier thread je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ClasseFille1 obj1 = new ClasseFille1();
    g_queue.push(obj1);
    puis dans mon autre thread, je recupère le premier élément de la queue. Mais est-ce que la fonction g_queue.pop() detruira le pointeur, comme un delete?

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    oui, je protège l'accès par une section critique.

    sinon, comment deleguer aux classes filles le traitement???? Ou bien, j'ai pas bien coompris le sens de la phrase...

  6. #6
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Citation Envoyé par cyrmaril Voir le message
    sinon, comment deleguer aux classes filles le traitement????
    En appelant une méthode virtuelle pure de la classe mère qui sera ré-implémentée dans les classes filles...

    MAT.

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    ok merci, je vais essayer tout ça!!

    Concernant mon problème graphique, une idée...??? serait-ce un problème de cohabitation de deux peekmessage (1 de la procedure du thread, l'autre de la fonction DoModal())??

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    en declarant des methodes virtuelles pures, ma classe mere devient abstraite.
    Du coup, je ne peux plus créer ma Queue queue<ClasseMere> g_queue!!!

  9. #9
    Membre du Club
    Inscrit en
    Août 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 40
    Points : 43
    Points
    43
    Par défaut
    Plutôt comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    queue<ClasseMere*> g_queue

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    j'ai pas d'autre choix que de passer par pointeur?

  11. #11
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    finalement je passe par pointeur et par le static_cast...

    Par contre, je m'apperçois que mon appli prend 100% de l'utilisation de l'UC!!!!!!!! Qu'est ce qui peut en être la cause dans une appli?

  12. #12
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 899
    Points : 1 916
    Points
    1 916
    Par défaut
    Citation Envoyé par cyrmaril Voir le message
    finalement je passe par pointeur et par le static_cast...
    dynamic_cast n'est-il pas plus approprié pour associer à un pointeur d'une classe fille un objet désigné par un pointeur d'une classe mère à l'exécution ?

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Déjà, le cast est-il vraiment nécessaire ? Une fonction virtuelle ne suffit-elle pas ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 899
    Points : 1 916
    Points
    1 916
    Par défaut
    Exact, effectivement, un cast n'est nécessaire que si l'on veut utiliser sur un objet de la classe fille, obtenu par un pointeur de la classe mère, une méthode qui n'est disponible que dans la classe fille.

    Citation Envoyé par cyrmaril Voir le message
    Mais est-ce que la fonction g_queue.pop() detruira le pointeur, comme un delete?
    Une std::queue<A*> contient des pointeurs sur des A, qui peuvent pointer sur des objets dérivés de la classe A. std::queue::pop() va détruire le pointeur, mais pas l'objet pointé, il faut le faire manuellement avec delete.

    Je poste un code pour illustrer mon propos, peut-être que ça t'aidera pour la std::queue (je ne connais pas encore les thread, par contre).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    #include <iostream>
    #include <queue>
     
    class A // Classe mère, abstraite
    {
    public:
    	virtual void execute() = 0; // Méthode virtuelle pure
    };
     
    class B : public A // Classe fille
    {
    public:
    	virtual void execute() { std::cout << "B" << std::endl;} // Méthode redéfinie
    };
     
    class C : public A // Classe fille
    {
    public:
    	virtual void execute() { std::cout << "C" << std::endl; } // Méthode redéfinie
    };
     
    int main()
    {
    	std::queue<A*> qa; // File de pointeurs sur des A
     
    	qa.push(new B); // Création dynamique d'objet, avec insertion d'un pointeur dans la file
    	qa.push(new C);
    	qa.push(new B);
     
    	while(qa.size() > 0) // Tant qu'il y a des objets dans la file
    	{
    		qa.front()->execute(); // Execution de l'opération de l'objet en cours
    		delete qa.front(); // Destruction de l'objet dynamique via son pointeur dans la file
    		qa.pop(); // Ejection du pointeur
    	}
     
    	system("pause");
     
    	return 0;
    }

  15. #15
    Membre habitué
    Profil pro
    Inscrit en
    Février 2003
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 224
    Points : 185
    Points
    185
    Par défaut
    http://msdn.microsoft.com/en-us/libr...f5(VS.80).aspx

    This member function handles all interaction with the user while the dialog box is active. This is what makes the dialog box modal; that is, the user cannot interact with other windows until the dialog box is closed.
    Ton problème vient que tu utilises DoModal, tu devrais créer une forme contenue dans une frame pour pouvoir en avoir plusieurs en vie.

  16. #16
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Pour répondre au cast, en effet, j'ai dans les classe filles des méthodes non disponibles dans ma classe mère.

    Mais si c'était pas le cas, en utilisant une fonction virtuelle, ma classe mère deviendrait abstraite et donc je ne pourrais plus créer la Queue composée de pointeurs de la classe mère, non? Est-ce que ce n'est vrai qu'avec des instances de classes?

    Pour le problème graphique, j'ai résolu mon problème : il s'agissait d'une erreur de ma part (je faisais un create() dans le constructeur de la classe avec laquelle j'appelais par la suite DoModal() ) donc nous ne pouviez pas savoir!!

    Encore merci pour tout!!

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    J'ai du mal à comprendre ce qui te fait croire que si une classe est abstraite, tu ne peux plus créer de pointeurs vers cette classe...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #18
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 899
    Points : 1 916
    Points
    1 916
    Par défaut
    Quand tu crées une classe, tu peux ensuite créer des instances de cette classe, ainsi que des pointeurs vers des objets de cette classe. Si cette classe est abstraite, tu ne peux pas créer d'instance, puisqu'elle n'est pas supposée être instanciée, mais que le code manquant est sensé être ensuite implémenté par des classes filles ; en revanche, tu peux toujours créer des pointeurs vers des objets appartenant à cette classe abstraite, qui pourront pointer vers des objets appartenant à des classes enfants, c'est d'ailleurs l'une des bases du polymorphisme.

    Un vector<T> sert à stocker des instances de T. Si T est une classe, on stockera des objets de cette classe. Si T est un pointeur vers des objets d'une classe, on stockera des pointeurs vers des objets de cette classe. Par conséquent, si on a une classe abstraite, on ne peut pas stocker des objets de cette classe abstraite, puisqu'elle ne peut être instanciée, mais on peut toujours stocker des pointeurs vers des objets de cette classe abstraite.

  19. #19
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    merci pour cette explication!!

Discussions similaires

  1. Modifier ListView dans un thread secondaire
    Par prologic dans le forum VB.NET
    Réponses: 16
    Dernier message: 09/01/2013, 09h19
  2. Executer une fonction (avec paramètres) dans un thread secondaire
    Par you38 dans le forum Threads & Processus
    Réponses: 21
    Dernier message: 06/08/2010, 08h12
  3. Fenêtres enfants dans un thread secondaire
    Par greg2 dans le forum Windows
    Réponses: 7
    Dernier message: 23/12/2009, 11h05
  4. appel système opendir dans thread
    Par madimane dans le forum POSIX
    Réponses: 2
    Dernier message: 14/04/2006, 05h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo