2010-03-26 11 views
14

Sto sviluppando una semplice libreria in C, per conto mio + alcuni amici uso personale.Esiste una soluzione alternativa per rendere un membro della struttura in qualche modo "privato" in C?

Attualmente ho una struttura C con alcuni membri che dovrebbero essere in qualche modo nascosti dal resto dell'applicazione, in quanto il loro uso è solo interno. Modificando per sbaglio uno di questi membri probabilmente renderà la libreria "selvaggia".

C'è qualche "soluzione alternativa" per nascondere tali membri in modo che non possano essere accessibili?

+0

Sembra che l'idea sia di mantenere la struttura "nascosta" nel file .c, dichiarando l'interfaccia di accesso nel file .h. Spero di aver capito bene! –

risposta

15

Il techique solito è questo:

/* foo.h */ 
typedef struct Foo Foo; 

Foo *foo_create(...); 

void foo_bark(Foo* foo, double loudness); 

/* foo.c */ 
struct Foo { 
    int private_var; 
}; 

È possibile nascondere parzialmente i dati membro definendo Foo nell'intestazione e FooPrivate nel file .c così:

struct FooPrivate { 
    Foo public_stuff; 
    int private_var; 
} 

Ma poi l'implementazione ha per lanciare avanti e indietro tra Foo e FooPrivate, che trovo essere una PITA reale, ed è un onere di manutenzione se cambi idea dopo e vuoi rendere qualcosa di privato. A meno che tu non voglia succhiare ogni ultimo ciclo della CPU dal codice, basta usare le funzioni accessorie.

+3

Puoi essere più specifico. :) –

+1

@nomemory, fornire solo un'interfaccia per aggiornare campi specifici, non rivelare la struttura. Come le funzioni foo_create e foo_bark, per esempio. –

+1

Nasconde il * intero * contenuto della 'struct', non campi specifici, quindi saranno necessari gli accessor. –

2

Marcelo Cantos ti ha già dato la risposta. Per informazioni più dettagliate, si dovrebbe esaminare come la struttura FILE sia effettivamente nascosta nella maggior parte delle librerie di uderlying.

Avreste notato che la struttura FILE di per sé non è mai disponibile per l'utente, solo le interfacce e un FILE Opaco * sono disponibili.

1

Fondamentalmente l'idea è di rinominare le variabili della struttura con qualcosa come un hash e scrivere funzioni (che sarebbero una sorta di metodi mimmici in lingue OO) per accedervi. Idealmente dovresti avere dei puntatori di funzione a quelle funzioni nella tua struct in modo da non chiamare per chiamare una funzione esterna e passarla hte struct a chi sono i membri che desideri aggiungere. Tuttavia la sintassi del puntatore di funzione non è nota per essere la più bella. Un semplice esempio che può chiarire ciò che è stato detto prima da Marcelo:

struct Car { 
    int _size; 
    char _colour[10]; 

}; 

typedef struct Car Car; 


int main (int argc, char **argv) { 
    Car *myCar= malloc(sizeof(Car)); 
    myCar->_size=5; /* accessing it directly just to set up a value, you shold have an 
         accessor function really */ 

    printf("car size is: %i \n",getCarSize(myCar)); 
    free(myCar); 
} 




int getCarSize(Car *myCar) { 
    return myCar->_size; 
} 
+0

È possibile che il codice passi attorno a un puntatore a una 'struct foo' senza sapere nulla sui contenuti della struct, ma la creazione di una variabile di tipo' struct foo' richiede di avere i suoi contenuti definiti. La punteggiatura di tipo tra diversi tipi di unione è definita se la dimensione e l'allineamento di entrambe le unioni sono vincolati dallo stesso tipo (ad esempio un 'long long [4]')? – supercat

1

Sono d'accordo con Marcelo Cantos, ma anche suggerire la semplice aggiunta di un puntatore all'interno della struttura "pubblica", che indica i contenuti "privati", es .:

/* foo.h */ 
typedef struct Bar Bar; 
typedef struct Foo 
{ 
    int public; 
    Bar* private; 
} Foo; 

Foo *foo_create(...); 

void foo_bark(Foo* foo, double loudness); 

/* foo.c */ 
struct Bar 
{ 
    int private_var; 
}; 

Questo approccio è un po 'come l'ideologia "pimpl". L'approccio più semplice è di fare ciò che Marcelo Cantos ha suggerito.

+0

Grazie, sembra che C possa supportare alcune funzionalità di "oop" con un piccolo sforzo da parte del programmatore :). –

Problemi correlati