Jakie są typowe konwencje nazewnictwa dla funkcji publicznych i prywatnych OO C? [Zamknięte]

12

Krótkie pytanie
Czy istnieje typowy sposób nazwania „publicznych” i „prywatnych” członków projektu OO C?

Tło
W pełni rozumiem, że członkowie publiczni i prywatni tak naprawdę nie istnieją w języku C. Jednak, podobnie jak większość programistów C, nadal traktuję członków jako publicznych lub prywatnych, aby zachować projekt OO. Oprócz typowych metod OO znalazłem siebie według wzoru (patrz przykład poniżej), który ułatwia mi rozróżnienie, które metody są przeznaczone dla świata zewnętrznego w porównaniu do członków prywatnych, którzy mogą mieć mniej kontroli / są bardziej wydajni itp. ... Czy istnieje taka standardowa lub najlepsza praktyka dla takich rzeczy, czy też mój przykład poniżej jest dobrym sposobem na zbliżenie się do tego?

Przykładowy nagłówek

#ifndef _MODULE_X_H_
#define _MODULE_X_H_

bool MOD_X_get_variable_x(void);
void MOD_X_set_variable_x(bool);

#endif /* _MODULE_X_H_ */

Przykładowe źródło

// Module Identifier: MOD_X 
#include "module_x.h"

// Private prototypes
static void mod_x_do_something_cool(void);
static void mod_x_do_something_else_cool(void);

// Private Variables
static bool var_x;

// Public Functions - Note the upper case module identifier
bool MOD_X_get_variable_x(void)      {return var_x;}
void MOD_X_set_variable_x(bool input){var_x = input;}

// Private Functions  - Note the lower case module identifier
void mod_x_do_something_cool(void){
     // Some incredibly cool sub routine 
}

void mod_x_do_something_else_cool(void){
     // Another incredibly cool sub routine 
}
Adam Lewis
źródło
2
+1 Za ciekawy temat: Projekt OO zaimplementowany w C! Podążę za twoim podejściem do deklarowania funkcji publicznych w pliku nagłówkowym i prywatnych jako funkcji statycznych w pliku implementacyjnym .c. Nie jestem jednak pewien, dlaczego potrzebujesz konkretnej konwencji nazewnictwa. Dlaczego nie użyć np. Wielkich liter do funkcji publicznych i prywatnych?
Giorgio
13
Bjarne Stroustrup opracował dość kompleksowy sposób pisania zorientowanego obiektowo C ...
Ant
Innym interesującym sposobem programowania obiektowego w języku C jest zestaw narzędzi graficznych Xt, znany programistom X11. Ref: en.wikipedia.org/wiki/X_Toolkit_Intrinsics
sdg
@Giorgio: Litery pisane wielkimi i małymi literami dla członków publicznych i prywatnych są takie, że podczas przeglądania kodu lub utrzymywania kodu jest on na pierwszy rzut oka znany, jeśli jest publiczny lub prywatny bez konieczności szukania deklaracji.
Adam Lewis
@Ant: Objective-C to kolejna możliwość. Myślę, że chodzi tutaj o to, że jeśli programujesz w C, nadal możesz używać projektowania OO. Oczywiście, jeśli często używam OOP, wybieram język OO.
Giorgio

Odpowiedzi:

17

Konwencja, której używam to:

  • Funkcja publiczna (w pliku nagłówkowym):

    struct Classname;
    Classname_functionname(struct Classname * me, other args...);
  • Funkcja prywatna (statyczna w pliku implementacji)

    static functionname(struct Classname * me, other args...)

Nie skupiaj się na obudowie. Chodzi o to, aby odróżnić dwie metody publiczne od dwóch klas, przygotowując przedrostek (nazwa klasy w tej konwencji).

Co więcej, OO-C to sposób, w jaki obiekt jest przekazywany jako pierwszy argument.

mouviciel
źródło
1
+1 Nie jestem wielkim ekspertem od C, ale to wygląda solidnie i poprawnie (nawet w kategoriach enkapsulacji, z którymi nigdy nie korelowałem z C - do tej pory).
Yam Marcovic
Uważaj na limity znaków identyfikatora narzucone przez niektóre kompilatory (np. 31 znaków dla niektórych!)
detly
8

Zwykle konwencja polega na tym, aby w ogóle nie umieszczać funkcji prywatnych w nagłówku .

Ponieważ zwykle umieszczasz implementację jednego obiektu w całości w jednym źródle, funkcja prywatna może zwykle mieć charakter statyczny. W takim przypadku zwykle pomijasz prefiks, aby zapisać trochę pisania (symbol nie będzie widoczny poza jednostką kompilacji).

Jeśli z jakiegoś powodu musisz udostępnić funkcję innej klasie, ale poza tym nadal jest prywatna, nazwij ją tak jak każdą inną metodę, ale umieść ją w osobnym nagłówku „-prywatnym”.

To samo dotyczy definicji typu. Jeśli to możliwe, deklarujesz w przód strukturę jako niekompletną w nagłówku i definiujesz ją w źródle lub w nagłówku „-private”. Potrzebujesz definicji, aby odziedziczyć klasę, więc traktowałbyś dodatkowy nagłówek jako coś chronionego niż prywatnego.


Prawdopodobnie największym kawałkiem kodu obiektowego w C jest platforma Gnome. Najłatwiej można zobaczyć konwencję w bibliotece GObject, która zapewnia klasy podstawowe najniższego poziomu . To z grubsza to, co opisałem powyżej i jest używane w całym Gnome.

Jan Hudec
źródło
Cieszę się, że dotknąłeś faktu, że symbol nie będzie widoczny poza jednostką kompilacji. Przyszło mi do głowy po rozmowie z kilkoma współpracownikami na ten temat. Jednak w celu wyjaśnienia, że ​​funkcje prywatne nie znajdują się w pliku nagłówkowym, są zadeklarowane statycznie w pliku C.
Adam Lewis
-1

Jeśli istnieje „klasa” w formie struktury, typu nieprzezroczystego lub podobnego, nazywam ją według:

typedef struct classname_t classname_t; 

Sufiks _t jest bardzo popularną konwencją nazewnictwa w C, używaną przez sam standard C. Rzadziej stosuje się wielką literę do klas / typów.

Następnie wymyśl prefiks nazw dla wszystkich funkcji publicznych. Zazwyczaj jakieś 3 litery. Wszystkie funkcje należące do klasy „jabłko” byłoby może być nazwane app_set_something(), app_get_something()etc.

Następnie będziesz chciał zastosować spójną konwencję nazewnictwa. W „konstruktor” może być nazwany app_init()lub app_construct(), w „destruktor app_clear(), app_destruct(), app_destroy()lub podobny. Użyj tej samej konwencji nazewnictwa dla wszystkich klas. Następnie zrób to samo dla funkcji setter / getter, i tak dalej.

Funkcje prywatne (statyczne) tak naprawdę nie potrzebują przedrostka klasy, ponieważ i tak nie są dostępne poza plikiem .c. Nadal możesz nadać im ten sam prefiks ze względów spójności lub po prostu nazwać je wszystkie prywatnym prefiksem, takim jak private_func(). Bardzo częstym sposobem jest nadawanie im nazw zaczynających się od znaku podkreślenia, ale jest to złe, ponieważ może kolidować z funkcjami biblioteki. Ściśle mówiąc, nie wolno używać identyfikatorów zaczynających się od znaku podkreślenia.

Nie zalecałbym używania wielkich liter jako sposobu na rozróżnienie między prywatnym a publicznym. Konwencja w prawie wszystkich standardach kodowania C jest taka, że ​​wszystkie duże litery oznaczają stałą, makro lub definicję preprocesora. Z tej konwencji korzysta sam standard C, interfejs API systemu Windows, jądro systemu Linux i tak dalej.


źródło
_t jest zastrzeżone.
Lilith River,