Ho visto il concetto di 'tipi opachi' gettato un po ', ma in realtà non ho trovato una risposta concisa su ciò che definisce un tipo opaco in C e, ancora più importante, quali problemi ci permettono di risolvere con la loro esistenza. GrazieCosa definisce un tipo opaco in C e quando sono necessari e/o utili?
risposta
È il più utilizzato per scopi di biblioteca. Il principale principio dietro Opaque digitare in c è quello di utilizzare i dati attraverso il puntatore per nascondere l'implementazione della gestione dei dati. Dal momento che l'implementazione è nascosta, è possibile modificare la libreria senza ricompilare tutti i programmi che dipendono da esso (se l'interfaccia è rispettato)
esempio: versione 1:
// header file
struct s;
int s_init(struct s **x);
int s_f(struct s *x);
int s_g(struct s *x);
// source file
struct s { int x; }
int s_init(struct s **x) { *x = malloc(...); }
int s_f(..) { ... }
int s_g(..) { ... }
versione 2
// header file
struct s;
int s_init(struct s **x);
int s_f(struct s *x);
int s_g(struct s *x);
// source file
struct s { int y; int x; }
int s_init(struct s **x) { *x = malloc(...); }
int s_f(..) { ... }
int s_g(..) { ... }
Dal lato del tuo programma, nulla è cambiato! e come detto in precedenza, non è necessario ricompilare ogni singolo programma che si basa su di esso.
Suppongo che le porzioni di '// implementazione' non siano separate dallo stesso '// file di intestazione' e che cosa vanno nelle librerie? Inoltre, sembra che tu abbia dichiarato 'struct s' nell'intestazione, ma non l'hai mai definito fino all'implementazione. Recentemente ho letto un ottimo post sulle variabili 'extern' in C http://stackoverflow.com/questions/1433204/what-are-extern-variables-in-c I concetti sembrano sorprendentemente simili, non dovrebbe essere' struct s' essere dichiarato come 'extern struct s' nel tuo codice di esempio? – SiegeX
utilizzando extern per variabile viene generalmente utilizzato per dichiarare la variabile globale (che non è assolutamente correlata al nostro caso). Qui l'istruzione struct s; è qui per indicare al compilatore un tipo chiamato struct s exist. Poiché tutte le API nel file di intestazione utilizzano SOLO il puntatore a questa struttura. Non ha bisogno di conoscere la dimensione della struttura ma la dimensione del puntatore della struttura (che è definita dal compilatore). Per semplificare, consente al programma di utilizzare un oggetto utilizzando il suo indirizzo (il puntatore alla struttura) – Phong
siegeX: ho cambiato il post per evitare la confusione sull'implementazione – Phong
A mio avviso, i tipi opachi sono quelli che consentono di tenere un handle (cioè un puntatore) a una struttura, ma non di modificarne o visualizzarne il contenuto direttamente (se è consentito a tutti, lo si fa attraverso le funzioni di supporto che capiscono la struttura interna).
I tipi opachi sono, in parte, un modo per rendere C più orientato agli oggetti. Consentono l'incapsulamento, in modo che i dettagli interni di un tipo possano cambiare o essere implementati in modo diverso in diverse piattaforme/situazioni, senza che il codice che lo utilizza debba essere modificato.
Quibble: questo idioma è * solo * sull'incapsulamento. L'incapsulamento è necessario per l'orientamento all'oggetto, ma è il più piccolo pezzo di esso. – dmckee
È vero, ci vuole molto più di questo per qualcosa quasi orientato agli oggetti. Eppure, è l'unica parte del design orientato agli oggetti che trovo * sempre * mancante quando scrivo in C. Plus, se tu * dovessi * cercare di emulare l'ereditarietà e il polimorfismo in C (più lavoro di quanto valga), avresti quasi certamente bisogno di iniziare con i tipi opachi. –
Ricorda che c e la cultura che ha generato risalgono a un periodo in cui l'orientamento degli oggetti era una cosa rara e ancora piuttosto sperimentale. Programmatori procedurali e funzionali del tempo concentrati di incapsulamento come * il * mezzo per controllare l'interconnettività e la complessità non necessaria. Parlare di tipi opachi in c come una sorta di oggetto storpio sta spingendo una POV estranea sulla lingua. - dmckee 10 minuti fa – dmckee
Un tipo opaco è un tipo esposto nelle API tramite un puntatore ma mai definito concretamente.
- 1. C++ definisce un tipo pressofuso
- 2. Che cosa sono kAudioSessionProperty_InputSources effettivamente utili?
- 3. Cosa significa il termine "tipo opaco" nel contesto di "tipo opaco CFBundleRef"?
- 4. Quando sono utili le Trasformazioni di Schwartz?
- 5. Cosa sono [e] in C#?
- 6. definisce un tipo Alias in C# in più file
- 7. - Sono necessari nome e ID?
- 8. Metodi nidificati? Perché sono utili?
- 9. Cosa definisce un thread "attivo"?
- 10. Cosa sono [] in C#?
- 11. Per cosa sono utili le globali di Ruby?
- 12. Quando i Generatori di espressioni ASP.NET sono più utili?
- 13. Cosa sono $ @ e $ <in un Makefile?
- 14. Cosa definisce "Dati privati" in VMMAP?
- 15. Cosa definisce operator()()?
- 16. Cosa sono oaidl.idl e ocidl.idl?
- 17. Sono veramente necessari scala.util.automata, scala.util.regexp e scala.util.grammar?
- 18. Cosa sono 1LL o 2LL in C e C++?
- 19. Sono necessari JRE e JDK per eseguire un file JAR?
- 20. Cosa sono NSBundle e mainBundle nell'obiettivo C?
- 21. Perché AutomationProperties sono necessari in WPF
- 22. Cosa si definisce ([, funzione]) in JavaScript?
- 23. I plug-in necessari sono installati automaticamente quando si installa un plug-in con dipendenze?
- 24. Quando GCC definisce NDEBUG?
- 25. Cosa sono `+:` e `-:`?
- 26. Sono ancora necessari gli attributi di tipo sugli elementi SCRIPT, STYLE e LINK?
- 27. C++ 11 definisce il tipo di funzione acquisita tramite riferimento
- 28. Cosa sono le "astrazioni"?
- 29. Come si definisce un tipo per una funzione in Scala?
- 30. In quali circostanze sono utili le proprietà atomiche?
'FILE' è un buon esempio di un tipo opaco nello standard C. Tutto ciò che ti serve è un oggetto 'FILE *' e usa le funzioni C standard che operano su di esso. Come programmatore non ti interessa cosa sia il tipo 'FILE'. –