Quelles sont les conventions de dénomination typiques pour les fonctions publiques et privées OO C? [fermé]

12

Question courte
Existe-t-il une manière typique de nommer les membres «publics» et «privés» d'un projet OO C?

Contexte
Je comprends parfaitement que les membres publics et privés n'existent pas vraiment en langage C. Cependant, comme la plupart des programmeurs C, je traite toujours les membres comme publics ou privés pour maintenir la conception OO. En plus des méthodes OO typiques, je me suis retrouvé à suivre un schéma (voir l'exemple ci-dessous) qui me permet de distinguer plus facilement les méthodes destinées au monde extérieur des membres privés qui peuvent avoir moins de contrôles / sont plus efficaces, etc. ... Existe-t-il une norme ou une meilleure pratique pour une telle chose ou mon exemple ci-dessous est-il un bon moyen d'aborder cela?

Exemple d'en-tête

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

Exemple de source

// 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
la source
2
+1 Pour le sujet intéressant: la conception OO implémentée en C! Je suivrais votre approche de déclaration des fonctions publiques dans le fichier d'en-tête et privées en tant que fonctions statiques dans le fichier d'implémentation .c. Je ne sais pas pourquoi vous avez besoin d'une convention de dénomination particulière. Pourquoi ne pas utiliser, par exemple, des majuscules pour les fonctions publiques et privées?
Giorgio
13
Bjarne Stroustrup a mis au point une méthode assez complète pour écrire du C orienté objet ...
Ant
Pour une autre façon intéressante de faire de la programmation basée sur des objets en C, vous pouvez consulter la boîte à outils graphiques Xt, familière aux programmeurs X11. Ref: en.wikipedia.org/wiki/X_Toolkit_Intrinsics
sdg
@Giorgio: L'intérêt des majuscules et des minuscules pour les membres publics et privés est que, lors de la révision du code ou de sa maintenance, il soit connu en un coup d'œil s'il est public ou privé sans avoir à rechercher une déclaration.
Adam Lewis
@Ant: Objective-C est une autre possibilité. Je pense que le point ici est que si vous programmez en C, vous pouvez toujours utiliser la conception OO. Bien sûr, si je fais un usage intensif de la POO, je vais pour une langue OO.
Giorgio

Réponses:

17

La convention que j'utilise est:

  • Fonction publique (dans le fichier d'en-tête):

    struct Classname;
    Classname_functionname(struct Classname * me, other args...);
    
  • Fonction privée (statique dans le fichier d'implémentation)

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

Ne vous concentrez pas sur le cas. Il s'agit de distinguer deux méthodes publiques de deux classes en ajoutant un préfixe (nom de classe dans cette convention).

De plus, ce qui fait OO-C est la façon dont l'objet est passé comme premier argument.

mouviciel
la source
1
+1 Pas un grand expert en C, mais cela a l'air solide et correct (même en termes d'encapsulation, que je n'ai jamais corrélé avec C - jusqu'à présent).
Yam Marcovic
Méfiez-vous des limites de caractères d'identification imposées par certains compilateurs (par exemple, 31 caractères pour certains!)
détly
8

Habituellement, la convention consiste à ne pas mettre du tout les fonctions privées dans l'en-tête .

Étant donné que vous placez normalement l'implémentation d'un objet entièrement dans une seule source, la fonction privée peut généralement être simplement statique. Dans ce cas, vous ignorez généralement le préfixe pour enregistrer une saisie (le symbole ne sera pas visible en dehors de cette unité de compilation).

Si, pour une raison quelconque, vous devez rendre la fonction disponible pour une autre classe, mais sinon toujours privée, vous la nommez comme n'importe quelle autre méthode, mais la placez dans un en-tête "-private" distinct.

Il en va de même pour la définition du type. Si possible, vous ne déclarez que la structure en tant que type incomplet dans l'en-tête et la définissez dans la source ou dans l'en-tête "-private". Vous avez besoin de la définition pour hériter de la classe, vous devriez donc traiter l'en-tête supplémentaire comme protégé plutôt que comme privé.


Le plus gros morceau de code orienté objet en C est probablement la plate-forme Gnome. Vous pouvez voir plus facilement la convention sur la bibliothèque GObject, qui fournit les classes de base de niveau le plus bas . C'est à peu près ce que je décris ci-dessus et est utilisé dans Gnome.

Jan Hudec
la source
Heureux que vous ayez évoqué le fait que le symbole ne sera pas visible à l'extérieur de l'unité de compilation. Cela m'est apparu après avoir discuté avec certains collègues de ce sujet. Cependant, pour clarifier, les fonctions privées ne sont pas dans le fichier d'en-tête, elles sont déclarées statiquement dans le fichier C.
Adam Lewis
-1

S'il existe une "classe" réelle, sous forme de struct, de type opaque ou similaire, je la nomme selon:

typedef struct classname_t classname_t; 

Le suffixe _t est une convention de dénomination très courante en C, utilisée par la norme C elle-même. Il est moins courant d'utiliser une majuscule pour les classes / types.

La prochaine chose que vous faites est de trouver un préfixe de dénomination pour toutes les fonctions publiques. Généralement, quelque chose de 3 lettres. Toutes les fonctions appartenant à la "classe apple" seraient peut-être nommées app_set_something(), app_get_something()etc.

Ensuite, vous souhaiterez utiliser une convention de dénomination cohérente. Le « constructeur » pourrait être nommé app_init()ou app_construct(), le « destructor app_clear(), app_destruct(), app_destroy()ou similaire. Utilisez la même convention de dénomination pour toutes vos classes. Faites de même pour les fonctions setter / getter, et ainsi de suite.

Les fonctions privées (statiques) n'ont pas vraiment besoin d'un préfixe de classe car elles ne sont de toute façon pas accessibles en dehors du fichier .c. Vous pouvez toujours leur donner le même préfixe pour des raisons de cohérence, ou peut-être simplement les nommer tous avec un préfixe privé, tel que private_func(). Une façon très courante consiste à leur donner des noms commençant par un trait de soulignement, mais cela est mauvais car il peut entrer en collision avec des fonctions de bibliothèque. À strictement parler, vous n'êtes pas autorisé à utiliser des identifiants commençant par un trait de soulignement.

Je ne recommanderais pas d'utiliser des majuscules pour distinguer le privé du public. La convention dans presque toutes les normes de codage C est que toutes les lettres majuscules indiquent une constante, une macro ou un pré-processeur défini. Cette convention est utilisée par la norme C elle-même, par l'API Windows, par le noyau Linux, etc.


la source
_t est réservé.
Lilith River