« Style Code » : différence entre les versions

De Wiki du LAMA (UMR 5127)
Aller à la navigation Aller à la recherche
Aucun résumé des modifications
(Ajout des conventions de JOL)
Ligne 160 : Ligne 160 :


#endif // _BYTEINPUT_H_
#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' <p>
* 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>
</source>

Version du 7 novembre 2009 à 15:29

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. - 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>