Se si desidera che le variabili private in c, ci sono un certo numero di tecniche che possono approssimare una variabile privata, ma il linguaggio C in realtà non ha un concetto di "protezione" che si estende a privato, pubblico, protetto (come C++ lo fa).
C mostrerà il nome di qualsiasi variabile (è un requisito in C), quindi è necessario avvicinarsi con l'idea di nascondere le informazioni del tipo della variabile (making dereferenziando abbastanza difficile).
Un trucco è quello definire la variabile come void*
con il tipo di variabile reale che è noto in un solo .c
modulo.
/* somefile.h */
extern void* counter;
/* somefile.c */
#include "somefile.h"
int actualCounter = 0;
void* counter = &actualCounter;
/* otherfile.c */
#include "somefile.h"
// we can see "counter", but we cannot "use" it here; because we don't have access
// to the real "hidden" type of "int".
Un metodo migliore è quello di estendere questa idea utilizzando la parola chiave struct
, e fare pseudo-metodi, in questo modo
/* person.h */
struct s_person;
typedef Person struct s_person;
Person* new_Person(char* name);
void delete_Person(Person* person);
void Person_setName(Person* person, char* name);
char* Person_getName(Person* person);
/* person.c */
struct s_person {
char* name;
};
Person* new_Person(char* name) {
Person* object = (Person*)malloc(sizeof(struct s_person));
// duplicate the string for more security, otherwise constructor
// could manipulate the "private" string after construction.
object->name = strdup(name);
return object;
}
void delete_Person(Person* person) {
// some implementations pass a Person** to set the reference to 0
// this implementation requires that the caller sets his own references to 0
free(person->name);
free(person);
}
void Person_setName(Person* person, char* name) {
// free the old
free(person->name);
// duplicate the new to provide "out of simulated class" modification by malicious
// name setter.
person->name = strdup(name);
}
char* Person_getName(Person* person) {
// must return a copy, otherwise one can manipulate name
// from reference provided by Person_getName(...);
return strdup(person->name);
}
/* otherfile.c */
#include "Person.h"
/* Now we can hold Person "simulated objects", but we cannot */
/* manipulate their "state" without using the C simulated object */
/* methods */
int main(int argc, char** argv) {
Person* bob = new_Person("bob");
printf("%s\n", Person_getName(bob));
delete_Person(bob);
// critical or we hold a pointer to freed memory.
bob = 0;
return 0;
}
Tecniche come questa hanno diverse varianti, uno è quello di avere un "struct pubblico "con un puntatore vuoto * alla" struttura privata ". Uno è quello di includere i "metodi" come puntatori di funzione nella "struttura pubblica" (un passo verso il supporto del polimorfismo), uno è scrivere un sistema di tipo C++ completo e corretto che tenta di risolvere le cose esattamente come farebbe il C++ (gerarchie di classi, polimorfismo, associazione tardiva, occultamento di informazioni, ecc.).
In sostanza, è possibile ottenere un po ' "object-oriented-ness", senza troppo lavoro, ma quando si aggiungono ulteriori funzionalità di -ornamentation, si aggiungerà più codice colla (fino a quando non è molto più semplice utilizzare effettivamente un linguaggio di programmazione orientato agli oggetti).
'C' non ha la nozione di' privato'. Forse provando a guardare le variabili globali 'static'. – RageD
Quindi la mia domanda. Come posso ingannare C? – Reid
Dipende da cosa stai cercando di fare. Dato che 'C' non è OOP (è orientato alla funzione), dovrai lavorare con funzioni e' struct's o variabili globali. – RageD