Ridefinizione di variabili globali con clausa "extern"
-
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 -
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):
Ho anche provato ad istanziare HRvbl, magari gli errori cambiano, ma ce ne sono sempre. Cosa faccio ?!?
-
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 esempioconst 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 tipoHRvbl::altezzaschermo = -1;
in main devi per forza togliere in const.P.S.
Di nuovo, dubito fortemente queste costanti ti servano sul serio -
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. -
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... -
@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? -
// 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:
-
Esatto, ti manca l'equivalente del
globali.cpp
che ho postato.
aggiungi un filehrnet_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)
-
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.
-
@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();
-
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 !!!
-
@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
inmain.cpp
. L'importante e' che non lo metti in multipli files .cpp