Partage
  • Partager sur Facebook
  • Partager sur Twitter

Ponteur d'un template dans une autre classe

Sujet résolu
    14 septembre 2018 à 10:52:55

    Bonjour,

    Dans un programme, j'ai passé des fonctions en template.

    Etant donné que j'utilise Q_OBJECT dans un template, j'ai du partager ma classe en deux, je me retrouve donc avec les deux classes suivantes :

    template <typename T>
    class __declspec(dllexport) TabView : public QTabWidget
    {
    public:
    	explicit TabView(QWidget *parent = nullptr);
    
    	int tabAt(const QPoint &pos);
    	QWidget *getPage(int index);
    	void closeThisTab(int index);
    	void closeCurrentTab(void);
    	void splitVertical(void);
    	void splitHorizontal(void);
    	void addNewTab(QAction *action);
    	void setCurrentTab(QAction *action);
    
    private:
    	LayoutButton *layoutButton;
    }; 
    template<typename T> class TabView;
    
    class LayoutButton : QPushButton
    {
    	Q_OBJECT
    
    public:
    	LayoutButton(TabView<T> *parent = nullptr);   // T inconnu
    	~LayoutButton(void);
    
    public slots:
    	void closeCurrentTab(void);
    	void splitVertical(void);
    	void splitHorizontal(void);
    	void addNewTab(QAction *action);
    	void setCurrentTab(QAction *action);
    
    private:
    	TabView<T> *tabView;   // T inconnu
    	void createToolActions();
    	void createToolMenu();
    	void createToolButton();
    
    	QAction *actionCloseTab;
    	QAction *actionSplitVertical;
    	QAction *actionSplitHorizontal;
    	QVector<QAction *> actionsAddTab;
    	QVector<QAction *> actionsSetTab;
    
    	QMenu *toolMenu;
    };


    Dans ma première classe, la classe template, j'ai un pointeur vers LayoutButton (avec l'include évidemment). Pour ça c'est bon.

    Le problème est dans la deuxième classe : layoutButton. Je n'arrive pas à intégrer un pointeur vers TabView.

    J'ai mis le prototype : "template<typename T> class TabView;" mais pourtant l'intégration du pointeur n'es pas bon, "T" reste inconnu dans la classe...

    Quelqu'un aurait-il une explication ?

    Merci d'avance

    -
    Edité par bozo6919 14 septembre 2018 à 10:53:59

    • Partager sur Facebook
    • Partager sur Twitter
    Toujours plus
      14 septembre 2018 à 11:18:12

      Heu, on peut vraiment exporter d'une Dll des classes templates ??? :-°
      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        14 septembre 2018 à 11:29:33

        Ne me dis pas que non stp :'( XD
        • Partager sur Facebook
        • Partager sur Twitter
        Toujours plus
          14 septembre 2018 à 11:45:35

          Je ne vois pas comment le compilateur et le linker pourrait se dépatouiller avec ça.

          Les templates du C++, c'est pas des génériques du C# ou de JAVA.

          (déjà, une API de Dll en C++, c'est pourri)

          Normalement, avec des templates, tout est dans les .h donc pas besoin de Dll/Lib.

          • Partager sur Facebook
          • Partager sur Twitter
          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
            14 septembre 2018 à 11:56:04

            Ok ok... Bon je verrai plus tard pour ça...

            Imaginons que je ne veux pas les exporter ^^ du coup, tu saurai comment faire pour mon problème ?

            • Partager sur Facebook
            • Partager sur Twitter
            Toujours plus
              14 septembre 2018 à 12:26:29

              Je ne vois pas où tu utilises T dans la déclaration de ta classe.

              Pourquoi un héritage privé de QPushButton ?

              Comme le dit bacelar, quand tu as des templates, tu dois generalement mettre les definitions des fonctions dans les headers. Donc avec une lib, tu n'as rien dans le DLL, ca sert a rien.

              Il y a quand meme un cas où, c'est utile, c'est si tu instanties explictement tes templates dans les sources. Dans ce cas, tu peux mettre les definitions de fonctions dans les sources. Mais tu perds la possibilité d'instancier le template en dehors de la lib.

              De toute façon, les QObject ne sont pas compatibles avec les templates. Je ne sais pas ce que tu veux faire, mais ca me semble problématique.

              Tu veux faire quoi ?

              • Partager sur Facebook
              • Partager sur Twitter
                14 septembre 2018 à 12:27:09

                Votre classe "LayoutButton", elle est template ou  pas ???

                Déjà que le couplage circulaire entre classe, c'est pas terrible, mais avec des classe template, comment dire. :-°

                • Partager sur Facebook
                • Partager sur Twitter
                Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                  14 septembre 2018 à 12:39:35

                  TabView<T> *tabView;   // T inconnu
                  Je suis parti du principe que oui, c'est une classe template.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    14 septembre 2018 à 12:44:14

                    LayoutButton n'était pas template non

                    Du coup je suis repartie en arrière dans mon projet, juste avant de mettre les templates. Là j'en ai plus, j'explique mon problème

                    je code avec visual studio, j'ai dans ma solution 2projets :

                    - EpiEditor --> exe

                    - MainLayout --> dll

                    EpiEditor se sert donc de mainLayout.

                    Dans MainLayout, j'ai une fonction dans la classe LayoutPanelBase qui dois utiliser une classe appartenant à EpiEditor (ce qui est en commentaire) :

                    LayoutPanelBase* LayoutPanelBase::parentLayoutPanel()
                    {
                    	QWidget *parent = parentWidget();
                    
                    	while (!dynamic_cast<LayoutPanelBase *>(parent)/* && !dynamic_cast<MainWindow *>(parent)*/)
                    		parent = parent->parentWidget();
                    	return dynamic_cast<LayoutPanelBase *>(parent);
                    }
                    

                    Le problème c'est que du coup la MainLayout ne connait pas MainWindow (classe de EpiEditor).

                    C'est de là que j'ai eu l'idée des templates.

                    Maintenant si il y a un autre moyen je suis preneur.

                    Est-ce qu'il est possible de stocker dans la classe LayoutPanelBase une variable template ? Si oui, j'aurai juste a faire un dynamique_cast de typeId(variable).name() ?

                    -
                    Edité par bozo6919 14 septembre 2018 à 12:46:17

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Toujours plus
                      14 septembre 2018 à 12:55:04

                      Comme l'a dit bacelar, tu as un probleme de references circulaires. Et là, c'est encore pire, puisque c'est entre ton exe et la lib. Donc c'est clairement une erreur de conception.

                      Qu'est ce que tu veux faire exactement ?

                      Hors sujet : n'utilises pas dynamic_cast, c'est souvent un problème de conception quand tu utilises ca. Avec Qt, tu es obligé parfois de faire du dynamique cast, mais préfère qobject_cast dans ce cas.

                      • Partager sur Facebook
                      • Partager sur Twitter
                        14 septembre 2018 à 13:06:24

                        Oui je vois bien mais ce que je voudrai c'est que MainLayout puisse marcher avec n'importe quelle nom de classe de EpiEditor

                        En gros MainLayout c'est une implémentation d'un systeme de layout avec des QTabWidget et TabBar dans des QSplitter etc...

                        Du coup j'ai mis ça en DLL et je voudrai la réutilisé pour n'importe quelle nom de classe. main du coup la fonction juste en haut dois s'adapter en fonction du nom, et c'est là ou je galère :/

                        Et pour qobject_cast oui je sais bien, mais si je mets qobject_cast il me demande la macro Q_OBJECT et en la mettant, la dll ne veut plus se créer

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Toujours plus
                          14 septembre 2018 à 14:38:30

                          Je ne connais pas Qt mais pour les MFC qui est aussi une bibliothèque graphique, l'utilisation de composant graphique dans des Dll est extrêmement contrainte. C'est des Dll d’extension MFC, qui imposent l'utilisation d'un nombre impressionnant de MACRO et de classe de base, de primitive de threading, de dispatching des messages, etc... .

                          Il y a de grande chance que cela soit le cas aussi avec Qt, voir que ce genre d'acrobatie ne soit pas du tout prise en compte.

                          Il faut au moins au minimum écumer la documentation de Qt sur cette problématique avant de réinventer une roue complètement carré, ou vous battre contre des moulins à vent.

                          Vous raisonnez qu'en terme de "nom de classe", poussé par l'apparente simplicité de template, mais là, vous êtes clairement pas dans les bons paradigmes.

                          Vous devriez concevoir une "classe/interface API" que votre exécutable implémenterait, et que votre Dll utiliserait. Cette classe serait dans un .h commun aux deux projets.

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                            14 septembre 2018 à 15:27:13

                            Du fait de l'utilisation des god objects avec Qt (QObject ou QWidget), on peut utiliser Qt dans les libs.

                            • Partager sur Facebook
                            • Partager sur Twitter
                              14 septembre 2018 à 16:02:39

                              Dac dac merci
                              • Partager sur Facebook
                              • Partager sur Twitter
                              Toujours plus
                                15 septembre 2018 à 1:08:55

                                Il me semble aussi, mais c'est peut être périmé, que dériver une classe template de QObject ne fonctionne pas car le MOC n'est pas capable de générer le code qui va bien derrière.

                                -
                                Edité par int21h 15 septembre 2018 à 1:11:32

                                • Partager sur Facebook
                                • Partager sur Twitter
                                Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
                                  15 septembre 2018 à 2:03:50

                                  gbdivers a écrit:

                                  De toute façon, les QObject ne sont pas compatibles avec les templates.

                                  Oui, c'est est encore vrai. Mais preum's :D

                                  (hors sujet : l'equipe de wobok avait implémenté une version du moc qui acceptait les templates - a priori, c'est pas complexe a faire - mais ca était refusé par Qt :D)

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    15 septembre 2018 à 2:12:40

                                    Ca m'apprendra à lire en diagonale ^^
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug

                                    Ponteur d'un template dans une autre classe

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                    • Editeur
                                    • Markdown