none
Programmazione modulare: ambito delle variabili, dichiarazione variabile esterna RRS feed

  • Domanda

  • Come rendere visibile a un modulo secondario, una variabile dichiarata nel modulo principale (quello della main)?

    Esempio: io ho un programma con il modulo principale "start.cpp", un modulo secondario "funz.cpp", e il file d'intestazione funz.h. Nel file "funz.cpp", io voglio usare la variabile "x" dichiarata nel file "start.cpp". Devo usare l'assegnazione "extern tipo nome variabile"? Inoltre, ponendo per esempio che il file "funz.cpp" abbia una funzione che mi restiutisce una variabile "y", che io userò nella main in "start.cpp", se io in questa funzione uso la variabile globale "x", tutti gli eventuali cambiamenti della variabile "x" in questa funzione, si rifletteranno sulla varriabile globale "x" (dichiarata nel modulo principale start.cpp)? 

    nota: io voglio usare la variabile globale "x", nella funzione in funz.cpp per evitare di passarla come parametro alla funzione. Per non passare troppi parametri alla funzione. Ma se non c'è alternativa potrei anche farlo.

    "insomma ho un po' di confusione sull'ambito delle variabili, utilizzando moduli secondari".


    beginner of planning

    martedì 19 aprile 2011 17:19

Risposte

  • 1-la variabile varGlob così dichiarata, ora non devo più dichiararla nel modulo principale? Ovvvero prima della main, io avevo dichiarato "int varGlob"; Questa riga la devo cancellare, e riscrivere il codice, anche nella main, sostituendo a varGlob, le chiamate a queste funzioni viste sopra?

    Hai azzeccato il concetto!!! :)

    2-Io posso fare quello che hai fatto con varGlob, con qualsiasi funzione che devo usare in tutti i moduli? Ovvero io ho nel modulo principale la funzione "esempio". Ho fatto un file d'intestazione contenente la firma di questa funzione e di altre che devo usare in tutti i moduli. Posso quindi eliminare questo file, e dichiarare la funzione esempio (e le funzioni che voglio usare in tutti i moduli) in stdafx.cpp,scriverne il prototipo in stdafx.h e quindi includere in tutti i moduli in cui voglio usare la funzione esempio stdafx.h, compreso il modulo principale. Ovviamente la funzione esempio, non verrà più dichiarata nel modulo principale. Giusto?

    Come sopra!!! :)

    • Contrassegnato come risposta Albitex mercoledì 20 aprile 2011 22:34
    mercoledì 20 aprile 2011 19:55

Tutte le risposte

  • Ciao Albitex,
    non ho ben capito le condizioni che vincolano le tue scelte, comunque cerco di interpretare e darti una risposta sulla base di quello che ho capito.
    Sinceramente l'uso delle extern in c++ è una tecnica sempre sconsigliata, se non altro perchè l'uso improprio che si è portati a farne porta alla perdita di controllo delle variabili così gestite.
    La tecnica che durante gli ultimi anni di programmazione in c++ mi ero abituato a utilizzare era sfruttare delle funzioni "Get" e "Set" della variabile interessata inserite nello stesso file in cui questa era definita e firmate nell'header file (il .h).
    In questo modo tutti i file che includevano il tuo header specifico (l'stdafx.h nel caso dovesse essere visto da tutto il progetto e nel caso di una windows application) potevano accede e modificare la variabile, ma il controllo era centralizzato (nell'stdafx.cpp).
    Spero di aver centrato il tuo problema, se hai bisogno di esempio, appena riesco a mettere le mani su un visual studio (o su del vecchio codice) ti invio qualche riga di codice.
    un saluto
    Andy74

    martedì 19 aprile 2011 18:52
  • Forse hai centrato il problema, ma cerco di esporlo ancora:

    allora io ho un modulo principale, dove c'è la main, io ho chiamato delle funzioni dichiarate nel modulo principale. Ho dovuto quindi fare un fail d'intestazione di questo e includerlo, perchè le funzioni fossero riconosciute. Idem ho dovuto fare un file d'intestazione del modulo secondario e includerlo nel modulo principale, per usare le funzioni di questul'ultimo nella main. Rimaneva il problema che variabili globali dichiarate nel modulo principale, non erano ovviamente riconosciute dal modulo secondario. (nel file d'intestazione io ho dichiarato solo i prototipi delle funzioni). Ho allora dichiarato delle variabili esterne nel modulo secondario. Ora nel visualizzatore degli oggetti, io trovo un doppione per ogni funzione/variabile usata in entrambi i moduli. Trovo l'oggetto funzione "x" e l'oggetto funzione "x" con una freccietta nera sopra il logo. L'oggetto con la freccietta nera, mi visualizza se cerco tutti i riferimenti, anche i riferimenti al modulo secondario.

    Ma tu mi dici che non è consigliabili dichiarare variabili esterne. Ma di usare Get e Set. Andrò a studiare queste funzioni.  Inoltre io non ho il file stdafx.cpp, perchè ho utilizzato un progetto vuoto, non precompilato. Il file d'intestazione .h del modulo principale lo creato io, includendo solo le funzioni che userò anche negli altri moduli.

     Aggiornamento: ho utilizzato un modello precompilato in VC++2010. Copiando il codice nel nuovo ambiente. Ora ho l'STDAFX.cpp e  STDAFX.h.  In STDAFX.h leggo la riga di commento:"// TODO: fare riferimento qui alle intestazioni aggiuntive richieste dal programma".  E in l'STDAFX.cpp leggo il commento:"/ TODO: fare riferimento alle intestazioni aggiuntive necessarie in STDAFX.H  e non in questo file". A questo punto, ti sarei molto grato una spiegazione su STDAFX, e forse ancora meglio qualche esempio di codice.

    (ma tu dirai: "già, ma non sono mica il suo professore d'informatica.."). Beh.. ti ringrazio molto per la disponibilità!

     


    beginner of planning


    • Modificato Albitex mercoledì 20 aprile 2011 17:54
    mercoledì 20 aprile 2011 01:33
  • Rieccomi Albitex,
    nessun problema.

    Dunque, rimaniamo sui file sdtafx.h e stdafx.cpp, che non sono altro che dei file di centralizzazione delle entità che contengono il necessario al tipo di progetto che stai implementando, come l'afxwin.h, le define per le direttive di precompilazione, ecc... (non a caso l'stdafx.h è incluso in tutti i moduli/classi esistenti/nuovi che vai a sviluppare).

    NOTA: lo stesso discorso lo si può comunque fare per file concepiti per lo stesso fine, come quelli creati da te.

    I metodi Get e Set di cui parlavo, non esistono, sono due metodi che devi creare tu per ogni singola variabile che vuoi rendere globale.

    Ipotiziamo che la tua variabile globale si chiami "varGlob" di tipo intero. La tua variabile sarà definita all'interno del file stdafx.cpp. In questo modo, tutti gli altri moduli, che includeranno l'stdafx.h, non possono ne vederla, ne tantomeno utilizzarla. La prima soluzione che hai trovato è quella della extern, ma abiamo detto che è meglio evitare. La soluzione alternativa è rendere disponibile a tutti i moduli delle funzioni specifiche che restituiscano (Get) e impostino (Set) la variabile, pur non conoscendone l'esistenza. Avendo tutti i moduli, l'stdafx.h in comune, possiamo sfruttare quello. Inserisci quindi all'interno dell'stdafx.h la definizione dei due metodi che chiameremo e firmeremo come segue:

     

    int Get_varGlob();
    void Set_varGlob(int valore);
    

     

    A questo punto devi implementare i metodi e lo farai nell'stdafx.cpp (dove c'è anche la definizione della tua variabile globale):

     

    int varGlob;
    
    int Get_varGlob()
    {
     return varGlob;
    }
    void Set_varGlob(int valore)
    {
     varGlob = valore;
    }
    
    

     

    A questo punto, tutti imoduli che hanno bisogno della variabile "varGlob" dovranno utilizzare i due metodi specifici. Non sarebbe errato inserire anche una funzione di inizializzazione della variabile stessa, per non incombere in valori inaspettati, o almeno inizializzare la variabile con il metodo Set_varGlob all'avvio della tua applicazione.

    Spero di essere stato chiaro e di non averti confuso ulteriormente.

    Qualora servisse, comunque, non  esitare.

    un saluto

    Andy74

    P.S.: scusa per le imprecisioni, non ho ancora un visual studio davanti e non scrivo in c++ ormai da anni, vado a memoria, spero di essermi ricordato tutto nel modo corretto! :D


    mercoledì 20 aprile 2011 06:36
  • int Get_varGlob();
    
    void Set_varGlob(int valore);
    
    

     A questo punto devi implementare i metodi e lo farai nell'stdafx.cpp (dove c'è anche la definizione della tua variabile globale):

     

     

    int varGlob;
    
    
    
    int Get_varGlob()
    
    {
    
     return varGlob;
    
    }
    
    void Set_varGlob(int valore)
    
    {
    
     varGlob = valore;
    
    }
    
    
    
    

     

    A questo punto, tutti imoduli che hanno bisogno della variabile "varGlob" dovranno utilizzare i due metodi specifici.

    Spero di essere stato chiaro e di non averti confuso ulteriormente.

    Quindi in ogni modulo, quando dovrò assegnare un valore a varGlob, dovrò chiamare la funzione Set_varGlob(int valore); mentre se vorrò "leggere" la variabile dovrò chiamare la funzione Get_varGlob(); Ma in pratica in questo modo, tu hai dichiarato le funzioni nel file stdafx.cpp, hai scritto i prototipi delle funzioni nel file d'intestazione stdafx.h, e quindi io le posso usare ora in ogni modulo in cui includo stdafx.h. Ma due domande:

    1-la variabile varGlob così dichiarata, ora non devo più dichiararla nel modulo principale? Ovvvero prima della main, io avevo dichiarato "int varGlob"; Questa riga la devo cancellare, e riscrivere il codice, anche nella main, sostituendo a varGlob, le chiamate a queste funzioni viste sopra?

    2-Io posso fare quello che hai fatto con varGlob, con qualsiasi funzione che devo usare in tutti i moduli? Ovvero io ho nel modulo principale la funzione "esempio". Ho fatto un file d'intestazione contenente la firma di questa funzione e di altre che devo usare in tutti i moduli. Posso quindi eliminare questo file, e dichiarare la funzione esempio (e le funzioni che voglio usare in tutti i moduli) in stdafx.cpp,scriverne il prototipo in stdafx.h e quindi includere in tutti i moduli in cui voglio usare la funzione esempio stdafx.h, compreso il modulo principale. Ovviamente la funzione esempio, non verrà più dichiarata nel modulo principale. Giusto?




     

     


    beginner of planning
    mercoledì 20 aprile 2011 17:46
  • 1-la variabile varGlob così dichiarata, ora non devo più dichiararla nel modulo principale? Ovvvero prima della main, io avevo dichiarato "int varGlob"; Questa riga la devo cancellare, e riscrivere il codice, anche nella main, sostituendo a varGlob, le chiamate a queste funzioni viste sopra?

    Hai azzeccato il concetto!!! :)

    2-Io posso fare quello che hai fatto con varGlob, con qualsiasi funzione che devo usare in tutti i moduli? Ovvero io ho nel modulo principale la funzione "esempio". Ho fatto un file d'intestazione contenente la firma di questa funzione e di altre che devo usare in tutti i moduli. Posso quindi eliminare questo file, e dichiarare la funzione esempio (e le funzioni che voglio usare in tutti i moduli) in stdafx.cpp,scriverne il prototipo in stdafx.h e quindi includere in tutti i moduli in cui voglio usare la funzione esempio stdafx.h, compreso il modulo principale. Ovviamente la funzione esempio, non verrà più dichiarata nel modulo principale. Giusto?

    Come sopra!!! :)

    • Contrassegnato come risposta Albitex mercoledì 20 aprile 2011 22:34
    mercoledì 20 aprile 2011 19:55