Style Code
Guillaume D. (CGAL like)
<source lang=cpp> /**
- Nom des classes, type, et paramètres templates avec 1ère lettre majuscule
- (tout le reste 1ère lettre minuscule)
- des _ entre les mots
- variables membres commencent par m
- variables paramètres commencent par a
- constantes en majuscules
- indentation : { et } sur la même colonne que le dessus et à
- l'intérieur décalage (type ANSI)
- /
template <Type> class Object_toto { public:
Object_toto(const Object_toto& atoto) { ... code indenté ... }
int is_valid() {}
private:
Type mdata;
static const int MA_CONSTANTE;
}
</source>
Seb F.
<source lang=cpp> /** -*- mode: c++ ; c-basic-offset: 3 -*-
* @file ByteInput.h * @author S. * @date Nov 2007 * * @brief Comme son nom l'indique * * @copyright // Informations sur la licence, etc. * * Puis détails. * * Conventions : * * - ClasseToto = ClasseToto.h + ClasseToto.cpp * (Ni plus, ni moins, sauf bien entendu si le .cpp est inutile). * - Le nom du fichier est exactement le nom de la classe. * - Identifiants : convention "CamelCase" * - Tous les identifiants de types utilisateurs commencent par des majuscules. * - Les constantes (pré-processeurs ou non) et valeurs de types énumérés sont * en majuscules. Mots séparés par "_". * - Un "#endif" indique par un commentaire la condition concernée. * - MAIS : "Avoid using the preprocessor whenever possible. [Stroustrup]" * (Perso, j'adhère.) * - Commentaire à la Javadoc (compatible avec Doxygen) * - Les données membres commencent par un underscore. * int _depth; * - Encapsulation (systématique). * - Un accesseur en lecture a le même nom que la donnée au "_" près. * Pas de getDepth() mais depth(); * - Une accesseur en écriture aussi. (Pas de "set"qqchose) * Pas de setDepth(int ) mais depth(int ); * - Les méthodes inline ne sont pas définies dans le corps de la * définition de classe mais en fin de .h (pas de code au sein * de la définition de classe). * - Indentation : variante K&R, cf. indentExample() * - Dans la mesure du possible, respecter 80 colonnes max. * (Indenter en fonction.) * - Ecriture "aérée" : espaces entre les opérateurs et les opérandes, à * l'intérieur des parenthèses, etc. * (Plutôt Java que C++, donc sans doute à ne pas adopter.) */
- ifndef _BYTEINPUT_H_
- define _BYTEINPUT_H_
- include "ByteInputFD.h"
- if defined(_IS_UNIX_) && defined(_HAS_GZIP_)
template< typename Type > class ByteInputGZip : public ByteInputFD {
public: /** * @param input Tous les paramêtres sont commentés. * * @return Ligne */ ByteInputGZip( ByteInput & input );
/** * Le commentaire décrit au présent de l'indicatif ce que fait la fonction * ou méthode. * * @param buff Tous les paramêtres sont commentés. * @param n Tous les paramêtres sont commentés. * * @return ... */ bool read( char *buff, size_t n );
inline void indentExample( int & a );
~ByteInputGZip();
inline ByteInput & in();
private:
ByteInputGZip( const ByteInputGZip & other );
protected:
ByteInput & _in; int _pidReader; /**< PID of the Stream input reader */ int _pidGZip; /**< PID of the GZip process */
};
/*
* Definitions of inline methods */
ByteInput & in() {
return _in;
}
/*
* */
void indentExample( int & a ) {
int i; for ( int i = 0; i < 100; ++i ) { if ( i % 2 ) {
std::cout << i << " est un nombre congru à 1 modulo 2 ";
} else {
std::cout << i << " est un nombre pair inférieur à 100 ";
} }
}
- endif // defined(_IS_UNIX_) && defined(_HAS_GZIP_)
- endif // _BYTEINPUT_H_
</source>
Jacques-Olivier L.
Conventions, structurations et qqs remarques
Un peu en vrac :
- nommage -# classes à la JAVA : DiscreteLine -# méthodes : bool isAligned() -# données membres : m_point -# constantes majuscules : NB_MAX_POINTS -# préprocesseur (évité autant que possible), sinon définitions _MYDEF_ - structuration -# tout dans un namespace -# découpage ensuite par répertoires (base, math, etc) -# une classe DiscreteLine : DiscreteLine.h DiscreteLine.ih DiscreteLine.cxx. Le fichier .ih contient le code des méthodes inline -# pas de fonctions ni de variables globales, plutôt des classes <<utils>>, sauf quelques opérateurs (operator<< par exemple). - intentions -# avoir des classes <<utils>> Trace, Debug, Timings pour homogéniser la gestion des erreurs. -# je n'utilise pas les exceptions en C++ quoique je le fais en JAVA, je ne suis pas contre en avoir. -# ajouter à chaque méthode sa complexité en pire cas, cas moyen, si cette méthode n'est pas O(1). -# ajouter un exemple d'utilisation à chaque exécutable. -# ajouter un exemple d'utilisation à chaque classe. - divers -# il faudrait générer nos classes avec un patron, pour être sûr que chaque fois qu'on rajoute du code, on suit la norme choisie. Je vous joins ci-dessous mes patrons : -# utiliser Doxygen pour générer la documentation de référence me semble indispensable -# Doxygen est aussi pas mal pour faire un peu de documentation utilisateur
Patron de XXX.h
<source lang=cpp> /** @file XXX.h */ ////////////////////////////////////////////////////////////////////////////// // // // File name : XXX.h // // Creation : 2000/??/?? // // Version : 2000/??/?? // // Author : JOL // // Summary : Header file for files XXX.ih and XXX.cxx // // History : // 2000/??/?? : ?Name? : ?What? // // Rcs Id : "@(#)class XXX declaration." // // ///////////////////////////////////////////////////////////////////////////////
- if defined(XXX_RECURSES)
- error Recursive header files inclusion detected in XXX.h
- else // defined(XXX_RECURSES)
- define XXX_RECURSES
- if !defined XXX_h
- define XXX_h
//////////////////////////////////////////////////////////////////////////////
- include <iostream>
//////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////// // Forces inline if nothing is provided by the compiler.
- ifndef INLINE
- define INLINE inline
- endif
namespace YYY {
///////////////////////////////////////////////////////////////////////////// // class XXX ///////////////////////////////////////////////////////////////////////////// /**
* Description of class 'XXX'
* Aim: */ class XXX { // ----------------------- Standard services ------------------------------ public: /** * Destructor. */ ~XXX(); // ----------------------- Interface -------------------------------------- public: /** * Writes/Displays the object on an output stream. * @param that_stream the output stream where the object is written. */ void selfDisplay( std::ostream & that_stream ) const; /** * Checks the validity/consistency of the object. * @return 'true' if the object is valid, 'false' otherwise. */ bool OK() const; // ------------------------- Datas ---------------------------------------- private: // ------------------------- Hidden services ------------------------------ protected: /** * Constructor. * Forbidden by default (protected to avoid g++ warnings). */ INLINE XXX(); private: /** * Copy constructor. * @param other the object to clone. * Forbidden by default. */ INLINE XXX( const XXX & other ); /** * Assignment. * @param other the object to copy. * @return a reference on 'this'. * Forbidden by default. */ INLINE XXX & operator=( const XXX & other ); // ------------------------- Internals ------------------------------------ private: }; /** * Overloads 'operator<<' for displaying objects of class 'XXX'. * @param that_stream the output stream where the object is written. * @param that_object_to_display the object of class 'XXX' to write. * @return the output stream after the writing. */ INLINE std::ostream& operator<<( std::ostream & that_stream, const XXX & that_object_to_display ); } // namespace YYY /////////////////////////////////////////////////////////////////////////////// // Includes inline functions/methods if necessary.
- if defined(INLINE)
- include "YYY/ZZZ/XXX.ih"
- endif
// // ///////////////////////////////////////////////////////////////////////////////
- endif // !defined XXX_h
- undef XXX_RECURSES
- endif // else defined(XXX_RECURSES)
</source>
patron de XXX.ih
<source lang=cpp>
////////////////////////////////////////////////////////////////////////////// // // // File name : XXX.ih // // Creation : 2000/??/?? // // Version : 2000/??/?? // // Author : JOL // // Summary : Implementation of inline methods defined in XXX.h // // History : // 2000/??/?? : ?Name? : ?What? // // Rcs Id : "@(#)class XXX declaration." // // ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// // IMPLEMENTATION of inline methods. ///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
- include <cstdlib>
- include <iostream>
//////////////////////////////////////////////////////////////////////////////
- if defined(NO_DEBUG)
- define ASSERT_XXX(x)
- define DEBUGCMD_XXX(x)
- else //defined(NO_DEBUG)
- define ASSERT_XXX(x) if(!(x)) \
{ std::cerr << "Assertion failed : (" << #x << ')' << std::endl \ << "In file : " << __FILE__ << " at line #" << __LINE__ << std::endl \ << "Compiled the " << __DATE__ << " at " << __TIME__ << std::endl; abort();}
- define DEBUGCMD_XXX(x) x
- endif // else defined(NO_DEBUG)
/////////////////////////////////////////////////////////////////////////////// // Implementation of inline methods //
///////////////////////////////////////////////////////////////////////////////
// Implementation of inline functions and external operators //
/**
* Overloads 'operator<<' for displaying objects of class 'XXX'. * @param that_stream the output stream where the object is written. * @param that_object_to_display the object of class 'XXX' to write. * @return the output stream after the writing. */
std::ostream& YYY::operator<<( std::ostream & that_stream, const XXX & that_object_to_display ) {
that_object_to_display.selfDisplay( that_stream ); return that_stream;
}
// // /////////////////////////////////////////////////////////////////////////////// </source>
patron de XXX.cxx
<source lang=cpp> /////////////////////////////////////////////////////////////////////////////// // // // File name : XXX.cxx // // Creation : 2000/??/?? // // Version : 2000/??/?? // // Author : Jacques-Olivier Lachaud // // email : lachaud@labri.fr // // Purpose : ?? // // Distribution : // // Use : // ?? // // Todo : // O ?? // // History : // 2000/??/?? : Mr ?Name? : ?What? // // ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// // //
///////////////////////////////////////////////////////////////////////////////
- include "YYY/ZZZ/XXX.h"
// Includes inline functions/methods if necessary.
- if !defined(INLINE)
- include "YYY/ZZZ/XXX.ih"
- endif
///////////////////////////////////////////////////////////////////////////////
using namespace std;
const char* const XXX_RCS_ID = "@(#)class XXX definition.";
/////////////////////////////////////////////////////////////////////////////// // class XXX ///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Standard services - public :
/**
* Destructor. */
YYY::XXX::~XXX() { }
/////////////////////////////////////////////////////////////////////////////// // Interface - public :
/**
* Writes/Displays the object on an output stream. * @param that_stream the output stream where the object is written. */
void YYY::XXX::selfDisplay( ostream& that_stream ) const {
that_stream << "[XXX]";
}
/**
* Checks the validity/consistency of the object. * @return 'true' if the object is valid, 'false' otherwise. */
bool YYY::XXX::OK() const {
return true;
}
/////////////////////////////////////////////////////////////////////////////// // Internals - private :
// // /////////////////////////////////////////////////////////////////////////////// </source>
Script de génération
Ces trois fichiers sont parsés par le script suivant, avec des paramètres ainsi :
genere.sh DiscreteLine digital2d ImaGene
<source lang=bash>
- !/bin/sh
if test "$#" != "3" ; then
echo "usage: $0 module_name namespace subdir" ; echo " creates three C++ skeleton files (.h .ih and .cxx) designed" echo " for a class [module_name]." exit 1
fi if test -w "$1.h" ; then
echo "File $1.h exists and is writable. Please remove it before." ; exit 2;
fi if test -w "$1.ih" ; then
echo "File $1.ih exists and is writable. Please remove it before." ; exit 2;fi
if test -w "$1.cxx" ;then
echo "File $1.cxx exists and is writable. Please remove it before." ; exit 2;
fi cho "Creating modules $1.h, $1.ih and $1.cxx" nspace="s/YYY/$2/g" subdir="s/ZZZ/$3/g" name="s/XXX/$1/g" today='s/2000\/??\/??/'`date '+20%y\/%m\/%d'`'/g'
cat "${HOME}/Modeles/C++/XXX2.h" | sed -e ${nspace} -e ${subdir} -e ${name} -e ${today} > "$1.h" cat "${HOME}/Modeles/C++/XXX2.ih" | sed -e ${nspace} -e ${subdir} -e ${name} -e ${today} > "$1.ih" cat "${HOME}/Modeles/C++/XXX2.cxx" | sed -e ${nspace} -e ${subdir} -e ${name} -e ${today} > "$1.cxx" echo "--> done."
</source>