Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Italian
  4. Ridefinizione di variabili globali con clausa "extern"
Forum Updated to NodeBB v4.3 + New Features

Ridefinizione di variabili globali con clausa "extern"

Scheduled Pinned Locked Moved Solved Italian
15 Posts 2 Posters 5.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    bvox123
    wrote on last edited by
    #1

    Buongiorno: rieccomi qua.
    Ieri pomeriggio ho postato una domanda simile a questa su un altro forum, ma è rimasta priva di risposta, quindi ci riprovo qui, avendo sperimentato che in questo forum ci sono dei guru più che esperti.
    Ho letto che se si vogliono creare delle variabili globali bisogna definirle al di fuori della main e ripeterle con l'apposizione static in tutte le classi in cui si usano.
    Dato che provengo da linguaggi in cui le classi non erano neppure immaginate (Assembler, Cobol, etc.) mi è difficile modificare la mia forma mentis di colpo e quindi ho pensato di fare un uso eccessivo di variabili globali. Il problema è che l'elenco di queste variabili è lungo (diciamo un centinaio) e doverle poi ripetere in tutte le classi che andrò a implementare diventerebbe un facile veicolo di errori. Per questo avrei pensato alla seguente soluzione.
    Creo un file header in cui le prime istruzioni sono le seguenti:

    #define TIPODATO extern
    #ifndef HRNET_0010_DICHIARATIVE_H
    #define HRNET_0010_DICHIARATIVE_H
    #define TIPODATO static
    #endif // HRNET_0010_DICHIARATIVE_H
    
    TIPODATO int larghezzaschermo = -1;
    TIPODATO int altezzaschermo = -1;
    TIPODATO int altezzabarra = -1;
    TIPODATO int quadroestrattix = -1;
    TIPODATO int quadroestrattiy = -1;
    TIPODATO int quadroestrattilarghezza = -1;
    TIPODATO int quadroestrattialtezza = -1;
    TIPODATO int quadrosingolonumerox = -1;
    TIPODATO int quadrosingolonumeroy = -1;
    TIPODATO int quadrosingolonumerolarghezza = -1;
    TIPODATO int quadrosingolonumeroaltezza = -1;
    

    Includendo questo header all'inizio della main e di tutte le classi dovrei avere nella main la variabile larghezzaschermo definita come "static int larghezzaschermo;" mentre nelle varie classi dovrebbe diventare "extern int larghezzaschermo".
    L'idea penso che potrebbe essere buona, ma... non funziona: perché ?
    Ecco gli errori che vengono fuori in compilazione:
    0_1500531313262_Schermata del 2017-07-20 08-14-52.png
    Mi date per favore qualche dritta ? Grazie.
    bvox

    1 Reply Last reply
    0
    • B Offline
      B Offline
      bvox123
      wrote on last edited by
      #2

      nessuno risponde... evidentemente è esageratamente fuori tema. "Quantunquemente" chiederò a Cetto Laqualunque. :-)

      1 Reply Last reply
      0
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by VRonin
        #3

        Premessa: se hai bisogno di tutti quei global probabilmente il tu design merita una rivisitazione...


        metti tutte le globali in una struct in un header file (ricorda gli include guards), assegna un valore in un cpp file e usali dove vuoi:

        globali.h

        #ifndef GLOBALI_H
        #define GLOBALI_H
        struct ContenitoreGlobali{
        static int larghezzaschermo;
        static int altezzaschermo;
        // etc.
        };
        #endif
        

        globali.cpp

        #include "globali.h"
        int ContenitoreGlobali::larghezzaschermo = -1;
        int ContenitoreGlobali::altezzaschermo = -1;
        // etc.
        

        ora puoi usarle usando ContenitoreGlobali::larghezzaschermo e ContenitoreGlobali::altezzaschermo dopo aver aggiunto #include "globali.h" all'inizio

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        0
        • B Offline
          B Offline
          bvox123
          wrote on last edited by
          #4

          Grazie VRonin. Segretamente contavo su una tua risposta. Devo dire che più o meno avevo tentato questa strada, ma avevo letto che le struct sono in pratica delle classi, quindi avevo provato ad istanziarla e forse questo è stato l'errore. Poi una descrizione degli errori che è molto fuorviante mi aveva fatto scegliere quell'altra soluzione, che però non funziona. Domani mi adeguerò ai tuoi suggerimenti.
          Grazie ancora.
          bvox

          1 Reply Last reply
          0
          • B Offline
            B Offline
            bvox123
            wrote on last edited by
            #5

            Non va... e non capisco il perché. Questo è il file header:

            #ifndef HRNET_0010_DICHIARATIVE_H
            #define HRNET_0010_DICHIARATIVE_H
            struct HRvbl {
                const int larghezzaschermo;
                const int altezzaschermo;
                const int altezzabarra;
            

            Questo è il main.cpp:

            #include "hrnet_0000_classeprincipale.h"
            #include "hrnet_0010_dichiarative.h"
            #include <QApplication>
            #include <QDesktopWidget>
            #include <iostream>
            int main(int argc, char *argv[])
            {
                QApplication applicazione(argc, argv);
                int HRvbl::larghezzaschermo = -1; // QApplication::desktop()->width();
                HRvbl::altezzaschermo = -1; // QApplication::desktop()->height();
            

            e questi sono gli errori di compilazione (non ci capisco niente):

            0_1500616242163_Schermata del 2017-07-21 07-49-54.png

            Ho anche provato ad istanziare HRvbl, magari gli errori cambiano, ma ce ne sono sempre. Cosa faccio ?!?

            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by VRonin
              #6

              stai usando const int altezzaschermo; ma non static come il mio post sopra. ti basta aggiunglo all'inizio: static const int altezzaschermo;

              Ora il secondo problema: se usi const il valore della variabili o e' conosciuto al momento della copilazione ad esempio const double pi_greco=3.14; o deve essere conosciuto quando la variabile e' "costruita" (brutta traduzione di constructed). Quindi, nel mio esempio sopra, il valore deve essere determinato in globali.cpp. se vuoi fare una cosa tipo HRvbl::altezzaschermo = -1; in main devi per forza togliere in const.

              P.S.
              Di nuovo, dubito fortemente queste costanti ti servano sul serio

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              1 Reply Last reply
              0
              • B Offline
                B Offline
                bvox123
                wrote on last edited by
                #7

                Straordinario. Ho scritto const ma intendevo dire static. La variabili non sono come il pigreco, sono proprio variabili che variano nel tempo. Capisco bene che l'idea di un centinaio di variabili è fuori logica, ma il più avanzato linguaggio di programmazione che ho un po' approfondito è stato il vb6: niente classi. Lasciami fare un po' di retrospezione.
                Con l'Assembler avevamo a disposizione non più di 50-60 vocaboli (istruzioni) e solo l'ingegno umano sapeva metterle insieme per realizzare pregetti informatici complessi. In fondo è a quei tempi che sono nati database gerarchici, soppiantati da quelli relazionali, metodi di compressione, sort e cose simili. Oggi i linguaggi si sono arricchiti di migliaia di forme di istruzioni, le classi, che hanno appesantito l'apprendimento degli stessi e il vantaggio di poter fare le cose più velocemente è solo un'utopia: chi ne ha una buona conoscenza fa tutto più velocemente, ma prima di arrivare a questa conoscenza, ne passa acqua sotto i ponti.
                Grazie VRonin, prometto che mi impegnerò meglio a "studiare" le classi e le sintassi per utilizzarle senza errori. Buon fine settimana.

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  bvox123
                  wrote on last edited by
                  #8

                  Ma la pseudo-classe contenente le mie dichiarative nella struct la devo istanziare ?
                  Mi sembra strano che se i riferimenti alle variabili li inserisco nella main li ritrova, mentre mettendoli in un'altra classe dice "riferimento non definito". Suppongo che sia perché il primo modulo ad essere compilato è la main e qui include l'header dichiarative, poi prosegue a compilare le altre classi, ma qui il #ifndef fa saltare l'include, quindi non trova quelle variabili. Torno alla prima ipotesi: definire due strutture di dichiarative uguali, ma la seconda con tutte le variabili con la clausola extern.
                  Purtroppo mi sto scoraggiando e sono solo all'inizio...

                  VRoninV 1 Reply Last reply
                  0
                  • B bvox123

                    Ma la pseudo-classe contenente le mie dichiarative nella struct la devo istanziare ?
                    Mi sembra strano che se i riferimenti alle variabili li inserisco nella main li ritrova, mentre mettendoli in un'altra classe dice "riferimento non definito". Suppongo che sia perché il primo modulo ad essere compilato è la main e qui include l'header dichiarative, poi prosegue a compilare le altre classi, ma qui il #ifndef fa saltare l'include, quindi non trova quelle variabili. Torno alla prima ipotesi: definire due strutture di dichiarative uguali, ma la seconda con tutte le variabili con la clausola extern.
                    Purtroppo mi sto scoraggiando e sono solo all'inizio...

                    VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by
                    #9

                    @bvox123 said in Ridefinizione di variabili globali con clausa "extern":

                    Ma la pseudo-classe contenente le mie dichiarative nella struct la devo istanziare ?

                    No. static serve a quello.

                    Mi sembra strano che se i riferimenti alle variabili li inserisco nella main li ritrova, mentre mettendoli in un'altra classe dice "riferimento non definito".

                    Puoi postare un esempio?

                    Hai generato una cosa come globali.cpp sopra?

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    1 Reply Last reply
                    0
                    • B Offline
                      B Offline
                      bvox123
                      wrote on last edited by
                      #10
                      // main.cpp
                      #include "hrnet_0000_classeprincipale.h"
                      #include "hrnet_0010_dichiarative.h"
                      #include <QApplication>
                      int main(int argc, char *argv[]) {
                          QApplication applicazione(argc, argv);
                          HRnet_0000 hrnet_0000;
                          hrnet_0000.show();
                          int codiceritorno;
                          codiceritorno = applicazione.exec();
                          return codiceritorno;
                      }
                      
                      #ifndef HRNET_0000_CLASSEPRINCIPALE_H
                      #define HRNET_0000_CLASSEPRINCIPALE_H
                      #include <QMainWindow>
                      #include <QWidget>
                      #include <QGroupBox>
                      #include <QLineEdit>
                      #include <QTextEdit>
                      #include <QRadioButton>
                      class HRnet_0000 : public QMainWindow {
                          Q_OBJECT
                      public:
                          HRnet_0000(QWidget *parent = 0);
                          ~HRnet_0000();
                      private:
                      //    QWidget *centralWidget;
                          QWidget *qt5hrnet1;
                          QWidget *qt5hrnet2;
                          QWidget *qt5hrnet3;
                      
                      #ifndef HRNET_0010_DICHIARATIVE_H
                      #define HRNET_0010_DICHIARATIVE_H
                      #include <QPoint>
                      struct HRvbl {
                          static int larghezzaschermo;
                          static int altezzaschermo;
                          static int altezzabarra;
                      
                      #include "hrnet_0000_classeprincipale.h"
                      #include "hrnet_0010_dichiarative.h"
                      #include <QApplication>
                      #include <QDesktopWidget>
                      #include <iostream>
                      HRnet_0000::HRnet_0000 (QWidget *parent) : QMainWindow(parent) {
                          HRvbl::larghezzaschermo = 111; // QApplication::desktop()->width();
                          HRvbl::altezzaschermo = QApplication::desktop()->height();
                      

                      e questo è l'elenco degli errori avendo spostato l'utilizzo delle variabili dalla main all'interno di una classe:

                      0_1500642553964_Schermata del 2017-07-21 15-09-00.png

                      1 Reply Last reply
                      0
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by
                        #11

                        Esatto, ti manca l'equivalente del globali.cpp che ho postato.
                        aggiungi un file hrnet_0010_dichiarative.cpp e mettici:

                        #include "hrnet_0010_dichiarative.h"
                        int HRvbl::larghezzaschermo = 0;
                        int HRvbl::altezzaschermo =0;
                        

                        i membri statici funzionano come i metodi: nel file h dici al compilatore che esistono (dichiarazione), nel file cpp chiarisci cosa fanno (definizione)

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        1 Reply Last reply
                        0
                        • B Offline
                          B Offline
                          bvox123
                          wrote on last edited by
                          #12

                          Quello che io avevo chiamato HRnet_0000_classeprincipale.cpp era proprio il corrispondente del tuo globali.cpp. Quindi il c++ è rigoroso anche nei nomi assegnati ai vari moduli ? In fondo il mio HRnet_0000 include il modulo HRnet_0010_dichiarative. E poi, anche se lo cambiassi di nome per renderlo simile all'header, non appena creassi una nuova classe non mi dirà che quella variabile non la riconosce ? Se la riconosce solo quando il nome del cpp è uguale al nome dell'header succederà così, penso. O no ? Se fosse così andrebbe a farsi friggere la mia idea di avere variabili globali da poter modificare in qualsiasi parte dell'applicativo.

                          1 Reply Last reply
                          0
                          • VRoninV Offline
                            VRoninV Offline
                            VRonin
                            wrote on last edited by
                            #13

                            @bvox123 said in Ridefinizione di variabili globali con clausa "extern":

                            Quello che io avevo chiamato HRnet_0000_classeprincipale.cpp era proprio il corrispondente del tuo globali.cpp

                            non nella sezione che hai postato almeno

                            @bvox123 said in Ridefinizione di variabili globali con clausa "extern":

                            c++ è rigoroso anche nei nomi assegnati ai vari moduli ?

                            No, assolutamente no, puoi chiamarli come vuoi


                            Un esempio:
                            hrnet_0010_dichiarative.h

                            #ifndef HRNET_0010_DICHIARATIVE_H
                            #define HRNET_0010_DICHIARATIVE_H
                            struct HRvbl {
                                // dichiaro
                                static int larghezzaschermo;
                                static int altezzaschermo;
                            }
                            #endif // HRNET_0010_DICHIARATIVE_H
                            

                            hrnet_0010_dichiarative.cpp

                            #include "hrnet_0010_dichiarative.h"
                            // definisco
                            int HRvbl::larghezzaschermo;
                            int HRvbl::altezzaschermo;
                            

                            hrnet_0000_classeprincipale.cpp

                            HRnet_0000::HRnet_0000 (QWidget *parent) : QMainWindow(parent) {
                            // uso
                                HRvbl::larghezzaschermo = 111; // QApplication::desktop()->width();
                                HRvbl::altezzaschermo = QApplication::desktop()->height();
                            

                            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                            ~Napoleon Bonaparte

                            On a crusade to banish setIndexWidget() from the holy land of Qt

                            1 Reply Last reply
                            0
                            • B Offline
                              B Offline
                              bvox123
                              wrote on last edited by
                              #14

                              Sì, posso chiamarli come voglio, ma a due a due. Nel senso che se ho creato il modulo PIPPO.H come dichiarativo, devo obbligatoriamente chiamare PIPPO.CPP il modulo che lo definisce. Inoltre, il modulo che lo definisce non è una classe, io avevo preteso di inserire le definizioni nella prima classe dopo la main. Bene, ora funziona. Sei grande !!!

                              VRoninV 1 Reply Last reply
                              0
                              • B bvox123

                                Sì, posso chiamarli come voglio, ma a due a due. Nel senso che se ho creato il modulo PIPPO.H come dichiarativo, devo obbligatoriamente chiamare PIPPO.CPP il modulo che lo definisce. Inoltre, il modulo che lo definisce non è una classe, io avevo preteso di inserire le definizioni nella prima classe dopo la main. Bene, ora funziona. Sei grande !!!

                                VRoninV Offline
                                VRoninV Offline
                                VRonin
                                wrote on last edited by
                                #15

                                @bvox123 said in Ridefinizione di variabili globali con clausa "extern":

                                se ho creato il modulo PIPPO.H come dichiarativo, devo obbligatoriamente chiamare PIPPO.CPP

                                No.

                                Dettaglio minore qui visto che di solito e' consigliato chiamare entrambi i file con lo stesso nome.

                                Per chiarire: i file .h non vengono compilati, solo i file .cpp (o .c) contano. Ogni file .cpp viene compilato in un "object" (.obj in MSVC). Il linker poi prende tutti questi files e li mette assieme per generare l'eseguibile. La restrizione (a cui accenni sopra parlando di extern) e' che il linker, se vede la stessa cosa in 2 objects non sa cosa fare e crea un errore. In pratica non puoi definire la stessa variabile in piu' files .cpp.

                                Puoi mettere l'intero contenuto di hrnet_0010_dichiarative.cpp in main.cpp. L'importante e' che non lo metti in multipli files .cpp

                                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                ~Napoleon Bonaparte

                                On a crusade to banish setIndexWidget() from the holy land of Qt

                                1 Reply Last reply
                                0

                                • Login

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved