Які типові угоди про іменування для державних та приватних функцій OO C? [зачинено]


12

Коротке запитання
Чи існує типовий спосіб назвати "публічних" та "приватних" членів проекту OO C?

Передумови
Я повністю розумію, що державні та приватні члени насправді не існують мовою С. Однак, як і більшість програмістів на C, я все ще відношусь до членів як до публічних чи приватних, щоб підтримувати дизайн ОО. На додаток до типових методів ОО, я виявив себе за шаблоном (див. Приклад нижче), що полегшує мені розрізнити, які методи призначені для зовнішнього світу проти приватних членів, які можуть мати менше перевірок / ефективніші тощо ... Чи існує стандарт чи найкраща практика для подібної речі чи мій приклад нижче хороший спосіб підійти до цього?

Приклад заголовка

#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_ */

Приклад Джерело

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

2
+1 На цікаву тему: OO-дизайн, реалізований на C! Я б дотримувався вашого підходу до оголошення загальнодоступних функцій у заголовковому файлі та приватних як статичних функцій у файлі .c реалізації. Я не впевнений, навіщо вам потрібна конкретна конвенція про іменування. Чому б не використовувати, наприклад, великі регістри як для публічних, так і для приватних функцій?
Джорджіо

13
Bjarne Stroustrup зібрав досить всебічний спосіб написання об'єктно-орієнтованого C ...
Ant

Ще один цікавий спосіб виконання об’єктного програмування на C ви можете подивитися графічний інструментарій Xt, знайомий програмістам X11. Ref: en.wikipedia.org/wiki/X_Toolkit_Intrinsics
sdg

@Giorgio: Справа у верхньому та нижньому регістрі для публічних та приватних членів полягає в тому, що при перегляді коду або збереженні коду з першого погляду відомо, чи є його публічним чи приватним, не шукаючи декларації.
Адам Льюїс

@Ant: Objective-C - це ще одна можливість. Я думаю, що тут справа в тому, що якщо ви програмуєте на C, ви все одно можете використовувати OO-дизайн. Звичайно, якщо я дуже використовую OOP, я переходжу до мови ОО.
Джорджіо

Відповіді:


17

Я використовую умову:

  • Загальнодоступна функція (у файлі заголовка):

    struct Classname;
    Classname_functionname(struct Classname * me, other args...);
    
  • Приватна функція (статична у файлі реалізації)

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

Не зосереджуйтесь на справі. Сенс полягає в тому, щоб відрізнити два загальнодоступні методи від двох класів, попередньо створивши префікс (назва класу в цій конвенції).

Більше того, що робить OO-C тим, як передається об'єкт як перший аргумент.


1
+1 Не великий експерт з С, але це виглядає міцно і правильно (навіть з точки зору інкапсуляції, яке я ніколи не співвідносив із C - до цього часу).
Ям Маркович

Остерігайтеся обмежень символів для ідентифікатора, встановлених деякими компіляторами (наприклад, 31 символ для деяких!)
дет

8

Зазвичай умовою є взагалі не ставити приватні функції в заголовок .

Оскільки ви зазвичай розміщуєте реалізацію одного об'єкта повністю в одному джерелі, приватна функція, як правило, може бути лише файл-статичною. У такому випадку ви зазвичай пропускаєте префікс, щоб зберегти деякий набір тексту (символ не буде видно поза цим блоком компіляції).

Якщо вам з якоїсь причини потрібно зробити функцію доступною для якогось іншого класу, але в іншому випадку все ще приватним, ніж ви називаєте його так само, як і будь-який інший метод, але помістіть його в окремий "-приват" заголовок.

Це ж стосується і визначення типу. Якщо це можливо, ви лише вперед оголошуєте структуру як неповний тип у заголовку та визначаєте її або в джерелі, або в заголовку "-private". Визначення потрібне для успадкування класу, тому ви будете ставитися до додаткового заголовка як до захищеного, а не до приватного.


Напевно, найбільший фрагмент об'єктно-орієнтованого коду на C - це платформа Gnome. Конвенцію можна легко побачити в бібліотеці GObject, яка забезпечує базові класи найнижчого рівня . Це приблизно те, що я описав вище, і використовується в усьому Gnome.


Радий, що ви торкнулися того, що символ не буде видно поза блоком компіляції. Мені приснилося після розмови з деякими колегами на цю тему. Однак для уточнення приватних функцій немає у заголовковому файлі, вони оголошуються статично у файлі C.
Адам Льюїс

-1

Якщо фактичний "клас" існує у вигляді структури, непрозорого типу або подібного, я називаю його відповідно до:

typedef struct classname_t classname_t; 

Суфікс _t - це дуже поширена умова іменування в C, використовується самим стандартом C. Менш поширеним є використання великої літери для класів / типів.

Наступне, що потрібно зробити - це придумати префікс імен для всіх публічних функцій. Зазвичай якась 3 буквена річ. Всі функції , що належать до «яблучної» класу буде , можливо , буде називатися app_set_something(), і app_get_something()т.д.

Тоді ви хочете використовувати послідовну конвенцію іменування. «Конструктор» може бути названий app_init()або app_construct(), то «деструкція app_clear(), app_destruct(), app_destroy()або аналогічний. Використовуйте ті ж правила іменування для всіх класів. Потім зробити те ж саме для функцій сетер / добувача, і так далі.

Приватним (статичним) функціям насправді не потрібен префікс класу, оскільки вони не доступні поза файлом .c. Ви все одно можете дати їм той самий префікс з міркувань послідовності або, можливо, просто назвати їх усі приватним префіксом, наприклад private_func(). Дуже поширений спосіб - дати їм імена, починаючи з підкреслення, але це погано, оскільки може зіткнутися з функціями бібліотеки. Строго кажучи, ви не можете використовувати ідентифікатори, починаючи з підкреслення.

Я б не рекомендував використовувати великі регістри як спосіб розрізнити приватне та публічне. Практично у всіх стандартах кодування на С є те, що всі літери верхнього регістру вказують на постійне, макро або попереднє визначення процесора. Ця конвенція використовується самим стандартом C, API Windows, ядром Linux тощо.


_t зарезервовано.
Річка Ліліт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.