« Style Code » : différence entre les versions

De Wiki du LAMA (UMR 5127)
Aller à la navigation Aller à la recherche
(Ajout des conventions de JOL)
Aucun résumé des modifications
Ligne 185 : Ligne 185 :
-# ajouter un exemple d'utilisation à chaque exécutable.
-# ajouter un exemple d'utilisation à chaque exécutable.
-# ajouter un exemple d'utilisation à chaque classe.
-# ajouter un exemple d'utilisation à chaque classe.
-# toute classe, méthode, données doit être commentée correctement.
- divers
- 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 :
-# 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
-# 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
-# Doxygen est aussi pas mal pour faire un peu de documentation utilisateur




=== Patron de XXX.h ===
=== Patron de XXX.h ===

Version du 7 novembre 2009 à 15:35

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.)
*/
  1. ifndef _BYTEINPUT_H_
  2. define _BYTEINPUT_H_
  1. include "ByteInputFD.h"
  1. 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 ";

     }
  }

}

  1. endif // defined(_IS_UNIX_) && defined(_HAS_GZIP_)
  1. 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. -# toute classe, méthode, données doit être commentée correctement. - 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." // // ///////////////////////////////////////////////////////////////////////////////

  1. if defined(XXX_RECURSES)
  2. error Recursive header files inclusion detected in XXX.h
  3. else // defined(XXX_RECURSES)
  4. define XXX_RECURSES
  1. if !defined XXX_h
  2. define XXX_h

//////////////////////////////////////////////////////////////////////////////

  1. include <iostream>

//////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////// // Forces inline if nothing is provided by the compiler.

  1. ifndef INLINE
  2. define INLINE inline
  3. 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.

  1. if defined(INLINE)
  2. include "YYY/ZZZ/XXX.ih"
  3. endif

// // ///////////////////////////////////////////////////////////////////////////////

  1. endif // !defined XXX_h
  1. undef XXX_RECURSES
  2. 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. ///////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

  1. include <cstdlib>
  2. include <iostream>

//////////////////////////////////////////////////////////////////////////////

  1. if defined(NO_DEBUG)
  2. define ASSERT_XXX(x)
  3. define DEBUGCMD_XXX(x)
  4. else //defined(NO_DEBUG)
  5. 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();}
  1. define DEBUGCMD_XXX(x) x
  2. 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? // // ///////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////// // //


///////////////////////////////////////////////////////////////////////////////

  1. include "YYY/ZZZ/XXX.h"

// Includes inline functions/methods if necessary.

  1. if !defined(INLINE)
  2. include "YYY/ZZZ/XXX.ih"
  3. 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>

  1. !/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>