2010-03-26 16 views
14

Pracuję nad prostą biblioteką w języku C, na użytek własny i kilka znajomych.Czy istnieje sposób obejścia problemu, aby członek struktury był w jakiś sposób "prywatny" w C?

Obecnie mam strukturę C z niektórymi członkami, które powinny być w jakiś sposób ukryte przed resztą aplikacji, ponieważ ich użycie jest tylko wewnętrzne. Modyfikowanie przez przypadek jednego z tych członków prawdopodobnie spowoduje, że biblioteka będzie "szaleć".

Czy istnieje "sposób obejścia", aby ukryć tych członków, aby nie byli dostępni?

+0

Wydaje się, że chodzi o to, aby zachować strukturę "ukrytą" w pliku .c, deklarując dostęp do interfejsu w pliku .h. Mam nadzieję, że rozumiem! –

Odpowiedz

15

Zazwyczaj techique to:

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

Foo *foo_create(...); 

void foo_bark(Foo* foo, double loudness); 

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

Można częściowo ukryć członków danych poprzez zdefiniowanie Foo w nagłówku i FooPrivate w pliku .c tak:

struct FooPrivate { 
    Foo public_stuff; 
    int private_var; 
} 

Ale wówczas realizacja ma rzucać w obie strony pomiędzy Foo i FooPrivate, które uważam za królewskie PITA, i jest to obciążenie konserwacyjne, jeśli później zmienisz zdanie i chcesz zrobić coś prywatnego. Chyba, że ​​chcesz wyssać każdy kod procesora poza kod, wystarczy użyć funkcji dostępu.

+3

Czy mógłbyś bardziej konkretny? :) –

+1

@nomemory, zapewniają tylko interfejs do aktualizacji określonych pól, nie ujawniają struktury. Na przykład funkcje foo_create i foo_bark. –

+1

To ukrywa * całą * treść pól 'struct', a nie konkretnych, więc konieczne będzie użycie akcesorów. –

2

Marcelo Cantos udzielił już odpowiedzi. Aby uzyskać bardziej szczegółowe informacje, należy przyjrzeć się, jak struktura PLIK jest skutecznie ukryta w większości bibliotek uderlying.

Zauważyłbyś, że sama struktura PLIK nigdy nie jest dostępna dla użytkownika, dostępne są tylko interfejsy i nieprzezroczysty PLIK *.

1

Zasadniczo chodzi o to, aby zmienić nazwy zmiennych za pomocą czegoś takiego jak hash i pisać funkcje (które mogłyby być rodzajem metod mimicznych w językach OO), aby uzyskać do nich dostęp. Idealnie powinieneś mieć wskaźniki funkcji dla tych funkcji w twojej strukturze, więc nie musisz wywoływać funkcji zewnętrznej i przekazywać jej struktury członkom, których chcesz dodać. Jednak składnia wskaźnika funkcji nie jest uważana za najpiękniejszą. Prostym przykładem, który może wyjaśnić, co zostało powiedziane wcześniej przez 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

Możliwe, że kod przechodzi przez wskaźnik do 'struct foo', nie wiedząc nic o zawartości struct, ale tworzenie zmiennej typu' struct foo' wymaga posiadania zdefiniowanej zawartości. Czy wykreśla się typ między różnymi typami związków, jeśli rozmiar i wyrównanie obu związków są ograniczone przez ten sam typ (np. "Długa długa [4]")? – supercat

1

zgadzam się z Marcelo Cantos, ale także zaproponować proste dodanie wskaźnika wewnątrz „publiczne” strukturze, co wskazuje na „prywatnych” treści, tj:

/* 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; 
}; 

Takie podejście jest podobne do ideału "pimpl". Najprostszym podejściem jest zrobienie tego, co sugerował Marcelo Cantos.

+0

Dzięki, wydaje się, że C może obsługiwać niektóre funkcje "oop" przy niewielkim wysiłku po stronie programisty :). –

Powiązane problemy