[C++] Come evitare di dichiarare globalmente
Salve avrei bisogno di un consiglio.
Devo utilizzare una funzione che tra i suoi parametri ha una variabile passata per indirizzo di tipo struttura .
Quando dichiaro il prototipo però sorge un problema dal momento che questi non riconosce il tipo struttura.
Ora io potrei risolvere il problema facendo una cosa del genere :
tuttavia vorrei evitare di dichiarare globalmente .
Quindi cosa mi consigliate di fare?
Devo utilizzare una funzione che tra i suoi parametri ha una variabile passata per indirizzo di tipo struttura .
#include <iostream> #include <cstring> #define N 50 using namespace std; void struttura_function(char a[N],char b[N],struttura *variabile,int index); int main() { struct struttura{ //ha diversi campi }; //altre istruzioni }
Quando dichiaro il prototipo però sorge un problema dal momento che questi non riconosce il tipo struttura.
Ora io potrei risolvere il problema facendo una cosa del genere :
#include <iostream> #include <cstring> #define N 50 using namespace std; struct struttura{ }; void struttura_function(char a[N],char b[N],struttura *variabile,int index); int main() { }
tuttavia vorrei evitare di dichiarare globalmente .
Quindi cosa mi consigliate di fare?
Risposte
[xdom="Raptorista"]Ciao, usa i tag per il codice nei tuoi messaggi, che così sono difficili da leggere.[/xdom]
Perché non vuoi mettere la dichiarazione come globale?
Perché non vuoi mettere la dichiarazione come globale?
Se il tuo problema è puramente estetico, ti consiglio di studiare le librerie e quindi di dichiarare le intestazioni (quindi prototipi e variabili globali) in un file a parte. Capirai tutto studiando le librerie e su YT trovi dei corsi semplicissimi.
Siccome la struttura è passata per riferimento puoi semplicemente dichiararla (la definizione sarà altrove). Si chiama "forward declaration" nel caso tu volessi fare qualche ricerca ulteriore a riguardo. In pratica puoi scrivere come segue:
Nota tuttavia che se nel main hai l'intenzione di creare una variabile ti tipo struttura o accedere ad una qualsiasi delle sue variabili membro o accedere alla sua dimensione, dovrai rendere visibile tale struttura nel main. Un modo è quello di definire tale struttura in un header file e includerlo in ogni file che ha bisogno di lavorare sulla tua struttura.
#include <iostream> #include <cstring> #define N 50 using namespace std; struct struttura; void struttura_function(char a[N], char b[N], struttura *variabile, int index); int main() { /* ... */ }
Nota tuttavia che se nel main hai l'intenzione di creare una variabile ti tipo struttura o accedere ad una qualsiasi delle sue variabili membro o accedere alla sua dimensione, dovrai rendere visibile tale struttura nel main. Un modo è quello di definire tale struttura in un header file e includerlo in ogni file che ha bisogno di lavorare sulla tua struttura.
"Omi":
su YT trovi dei corsi semplicissimi.
Attenzione con le risorse online. C'è una quantità immensa di materiale sul C++, la maggior parte del quale è di pessima qualità.
Se è un problema di linking puoi definire la struttura in un namespace.
Eh però mettere [tt]struttura[/tt] in f.d. sullo spazio globale è la stessa cosa di dichiararla completamente (più o meno, ad esempio se ha dati di tipi noti sul globale). Scavando tra quel poco di C++ che ricordo (e che ho imparato nel periodo che ho trascorso in un ITIS, quindi non è che sia "chissà cosa"), credo che la cosa migliore sia mettere la dichiarazione della struttura e la firma della funzione in un header.
Tieni presente che se in un .cpp avrai bisogno di utilizzare [tt]struttura_function[/tt], questo avverrà chiamandola su un oggetto di tipo [tt]struttura[/tt], che dovrà in qualche modo essere già stato definito[nota]L'esercizio mi sembra un'imitazione di OOP fatta in C, quindi credo che [tt]struttura_function[/tt] impersoni di fatto un metodo, rendendo lecito mettere nello stesso header dati e cose-che-operano-sui-dati.[/nota]; supponendo però che l'implementazione di [tt]struttura_function[/tt] necessiti di far ricorso ad un numero imprecisato di headres esterni (pensa semplicemente agli algoritmi di STL) completamente inutili nel resto del codice, con l'importazione di [tt]struttura.hpp[/tt] risolvi il problema una volta per tutte, ché l'implementazione rimane isolata sul .cpp di implementazione. Ah probabilmente a distanza di due anni e mezzo dall'ultima volta che ho pensato a ciò, ho usato in modo casuale alcuni termini tecnici, spero sia chiaro lo stesso
(struttura.hpp)
(struttura.cpp)
Tieni presente che se in un .cpp avrai bisogno di utilizzare [tt]struttura_function[/tt], questo avverrà chiamandola su un oggetto di tipo [tt]struttura[/tt], che dovrà in qualche modo essere già stato definito[nota]L'esercizio mi sembra un'imitazione di OOP fatta in C, quindi credo che [tt]struttura_function[/tt] impersoni di fatto un metodo, rendendo lecito mettere nello stesso header dati e cose-che-operano-sui-dati.[/nota]; supponendo però che l'implementazione di [tt]struttura_function[/tt] necessiti di far ricorso ad un numero imprecisato di headres esterni (pensa semplicemente agli algoritmi di STL) completamente inutili nel resto del codice, con l'importazione di [tt]struttura.hpp[/tt] risolvi il problema una volta per tutte, ché l'implementazione rimane isolata sul .cpp di implementazione. Ah probabilmente a distanza di due anni e mezzo dall'ultima volta che ho pensato a ciò, ho usato in modo casuale alcuni termini tecnici, spero sia chiaro lo stesso

(struttura.hpp)
#ifndef __STRUTTURA__ #define __STRUTTURA__ struct struttura { // dati }; void struttura_function(char a[N], char b[N], struttura &variabile, int index); /* perché usi un puntatore e non &? e char[] al posto di std::vector<char> o (che credo sia il tuo caso) std::string? (ricordo che fanno risparmiare tante bestemmie) */ #endif
(struttura.cpp)
#include "struttura.hpp" void struttura_function(char a[N], char b[N], struttura &variabile, int index) { // cose }
"marco2132k":
Eh però mettere [tt]struttura[/tt] in f.d. sullo spazio globale è la stessa cosa di dichiararla completamente (più o meno, ad esempio se ha dati di tipi noti sul globale). Scavando tra quel poco di C++ che ricordo (e che ho imparato nel periodo che ho trascorso in un ITIS, quindi non è che sia "chissà cosa"), credo che la cosa migliore sia mettere la dichiarazione della struttura e la firma della funzione in un header.
Una struttura deve essere dichiarata/definita in ogni unità di compilazione per poter essere utilizzata. La visibilità di questa definizione è "globale" solo se inclusa in diverse unite di compilazione. Una struttura dichiarata o definita all'interno di un header incluso in diverse unità di compilazione è quindi certamente più globale di una struttura definita all'interno di un singolo codice sorgente. Le operazioni che puoi fare su un tipo opaco sono inoltre molto più limitate rispetto ad una struttura di cui si conosce il contenuto. Puoi infatti creare solo puntatori o riferimenti e non puoi ottenerne la dimensione o fare aritmetica dei puntatori. È in effetti un metodo classico in C per definire strutture il cui contenuto si vuole tenere privato.
"marco2132k":
Tieni presente che se in un .cpp avrai bisogno di utilizzare [tt]struttura_function[/tt], questo avverrà chiamandola su un oggetto di tipo [tt]struttura[/tt], che dovrà in qualche modo essere già stato definito; supponendo però che l'implementazione di [tt]struttura_function[/tt] necessiti di far ricorso ad un numero imprecisato di headres esterni (pensa semplicemente agli algoritmi di STL) completamente inutili nel resto del codice, con l'importazione di [tt]struttura.hpp[/tt] risolvi il problema una volta per tutte, ché l'implementazione rimane isolata sul .cpp di implementazione. Ah probabilmente a distanza di due anni e mezzo dall'ultima volta che ho pensato a ciò, ho usato in modo casuale alcuni termini tecnici, spero sia chiaro lo stesso
Non tutte le funzioni che operano su una struttura o classe sono necessariamente accoppiate alla classe. In effetti è in generale meglio ridurre il numero di funzioni membro in favore di funzioni che utilizzano solo la parte pubblica della classe. Non c'è nulla di sbagliato in questo caso, probabilmente è la scelta corretta, ma non deve essere presa con una regola generale.
Ho l'impressione comunque che il corso sia più di C che di C++ (al massimo usando cose come std::cout) e che sia chiamato C++ principalmente perché viene usato un compilatore C++.