OVH Cloud OVH Cloud

Module et namespace

8 réponses
Avatar
Michael
Bonsoir à tous,

je me pose une question concernant la déclaration et l'utilisation des
namespaces.

J'ai créé toute une série de classes (une bonne trentaine) au sein d'un
module de montage vidéo.

Dans chaque .H, j'ai la déclaration de mes classes dans un namespace
Montage.

#ifndef fooH
#define fooH

namespace Montage
{
class foo
{
public:
foo();
};
}

#endif

Mais je ne vois pas trop quelle est la meilleure méthode concernant les
fichiers .CPP. J'hésite entre 3 méthodes:

/////////// Méthode 1 \\\\\\\\\\\\\
#include "foo.h"

namespace Montage
{
foo::foo()
{

}
}

/////////// Méthode 2 \\\\\\\\\\\\\
#include "foo.h"

using namespace Montage

foo::foo()
{

}

/////////// Méthode 3 \\\\\\\\\\\\\
#include "foo.h"

Montage::foo::foo()
{

}


La méthode 2 est bien entendu la plus pratique, parce que ça m'évite de
tout préfixer comme avec la méthode 3, mais ne risque-t-il pas d'y avoir
éventuellement des conflits quand j'utiliserai ce module dans d'autres
projets?

Pour l'instant, j'ai opté pour la méthode 3. Le code est un peu plus
long, mais ça ne me dérange pas tant que ça...

Quelle méthode utilisez-vous?

Merci d'avance

Mike

8 réponses

Avatar
Patrick Mézard
Bonsoir à tous,

je me pose une question concernant la déclaration et l'utilisation des
namespaces.

[...]


Mais je ne vois pas trop quelle est la meilleure méthode concernant les
fichiers .CPP. J'hésite entre 3 méthodes:

/////////// Méthode 1 \\\
#include "foo.h"

namespace Montage
{
foo::foo()
{

}
}

/////////// Méthode 2 \\\
#include "foo.h"

using namespace Montage

foo::foo()
{

}

/////////// Méthode 3 \\\
#include "foo.h"

Montage::foo::foo()
{

}


La méthode 2 est bien entendu la plus pratique, parce que ça m'évite de
tout préfixer comme avec la méthode 3, mais ne risque-t-il pas d'y avoir
éventuellement des conflits quand j'utiliserai ce module dans d'autres
projets?


Je pense que si.
Je n'ai jamais fabriqué de cas où cela arrivait, mais j'ai l'impression
que [1] et [3] reposent sur de la déclaration explicite alors que [2]
s'appuie uniquement sur le mécanisme de recherche de noms et est donc
sujet à ambiguité. J'ai même un peu de mal à comprendre comment [2] fait
pour marcher (cela passe avec tous les compilateurs que je connais).
Mais bon je peux me tromper.

Pour l'instant, j'ai opté pour la méthode 3. Le code est un peu plus
long, mais ça ne me dérange pas tant que ça...

Quelle méthode utilisez-vous?


La [1]. Quel est l'intérêt de la [3] par rapport à la [1] ? Elle est
plus verbeuse et je ne vois pas ce qu'elle apporte (à part lever toute
polémique d'indentation de code :-)).

Patrick Mézard

Avatar
Michael
Merci de ta réponse.

Des recherches en parallèle sur google m'ont également donné cette
réponse...
Avatar
Serge Paccalin
Le mardi 20 décembre 2005 à 23:31:39, Michael a écrit dans
fr.comp.lang.c++ :

/////////// Méthode 1 \\\
#include "foo.h"


Évite ce style de commentaire, sinon un jour tu t'en mordras les doigts.

--
___________ 21/12/2005 21:14:25
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763

Avatar
Matthieu Moy
Serge Paccalin writes:

Le mardi 20 décembre 2005 à 23:31:39, Michael a écrit dans
fr.comp.lang.c++ :

/////////// Méthode 1 \\\
#include "foo.h"


Évite ce style de commentaire,


Je suppose que tu veux dire « les commentaires se terminant par un
''. ». Je confirme !

--
Matthieu


Avatar
Falk Tannhäuser
Matthieu Moy wrote:
Serge Paccalin writes:
Le mardi 20 décembre 2005 à 23:31:39, Michael a écrit dans
fr.comp.lang.c++ :
/////////// Méthode 1 \\\
#include "foo.h"


Évite ce style de commentaire,


Je suppose que tu veux dire « les commentaires se terminant par un
''. ». Je confirme !


Là il s'agit plutôt d'un commentaire se terminant par
'#include "foo.h"' :-P

Falk



Avatar
Michael
Serge Paccalin wrote in
news::

Le mardi 20 décembre 2005 à 23:31:39, Michael a écrit dans
fr.comp.lang.c++ :

/////////// Méthode 1 \\\
#include "foo.h"


Évite ce style de commentaire, sinon un jour tu t'en mordras les doigts.



Je n'utilise jamais, c'était juste pour bien dissocier les différentes
méthodes auxquelles je pensais ;)


Avatar
kanze
Patrick Mézard wrote:

je me pose une question concernant la déclaration et
l'utilisation des namespaces.


[...]

Mais je ne vois pas trop quelle est la meilleure méthode
concernant les fichiers .CPP. J'hésite entre 3 méthodes:

/////////// Méthode 1 \\\
#include "foo.h"

namespace Montage
{
foo::foo()
{

}
}

/////////// Méthode 2 \\\
#include "foo.h"

using namespace Montage

foo::foo()
{

}

/////////// Méthode 3 \\\
#include "foo.h"

Montage::foo::foo()
{

}


La méthode 2 est bien entendu la plus pratique, parce que ça
m'évite de tout préfixer comme avec la méthode 3, mais ne
risque-t-il pas d'y avoir éventuellement des conflits quand
j'utiliserai ce module dans d'autres projets?



Peut-être. Il suffit qu'il y a un autre class foo visible, soit
en namespace global, soit dans un autre namespace dont on a fait
using namespace.

Je pense que si.

Je n'ai jamais fabriqué de cas où cela arrivait, mais j'ai
l'impression que [1] et [3] reposent sur de la déclaration
explicite alors que [2] s'appuie uniquement sur le mécanisme
de recherche de noms et est donc sujet à ambiguité.


Formellement, toutes les méthodes s'appuie sur le mécanisme de
recherche de noms. Seulement, avec [1] et [3], la recherche se
limite bien à l'espace référentiel Montage ; avec [2], il inclut
l'espace global et tous les espaces référentiel qui ont été
l'objet d'un directif using.

En fait, je crois qu'il y a même une légère différence entre [1]
et [3]. Si j'ai bien compris la norme ici, dans [1], on va
chercher foo d'abord dans Montage, et si on ne l'y trouve pas
(mais seulement si on ne le trouve pas), ensuite dans l'espace
global. Dans [3], s'il n'y a pas de classe foo dans Montage,
c'est une erreur.

Mais il y a aussi une phrase (§9.3/2) « A member function
definition that appears outside of the class definition shall
appear in a namespace scope enclosing the class definition. Ce
qui fait que si, dans [1], on ne trouve la définition de foo que
dans l'espace référentiel global, c'est une erreur.

Dans la pratique, je n'ai jamais vu que [1]. (Mais mon
expérience avec les espaces référentiels est extrèmement
limitée.)

J'ai même un peu de mal à comprendre comment [2] fait pour
marcher (cela passe avec tous les compilateurs que je
connais). Mais bon je peux me tromper.


On recherche d'abord une classe (ou un espace référentiel) nommé
foo. Grace à la directive d'using, on trouve bien la classe
Montage::foo. Ensuite, tout se passe comme dans les autres cas.

Pour l'instant, j'ai opté pour la méthode 3. Le code est un
peu plus long, mais ça ne me dérange pas tant que ça...

Quelle méthode utilisez-vous?


La [1]. Quel est l'intérêt de la [3] par rapport à la [1] ?
Elle est plus verbeuse et je ne vois pas ce qu'elle apporte (à
part lever toute polémique d'indentation de code :-)).


Elle rend immédiatement visible ce qu'on est en train de
définir.

Le problème avec [3], c'est qu'on ne peut pas l'utiliser pour
des espaces référentiels anonymes. Or, typiquement, on n'a qu'un
seul espace référentiel nommé, et l'espace anonyme, dans une
module, et c'est bien entre ces deux-là qu'on aimerait le plus
distinguer.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
kanze
Falk Tannhäuser wrote:
Matthieu Moy wrote:
Serge Paccalin writes:
Le mardi 20 décembre 2005 à 23:31:39, Michael a écrit dans
fr.comp.lang.c++ :
/////////// Méthode 1 \\\
#include "foo.h"


Évite ce style de commentaire,


Je suppose que tu veux dire « les commentaires se terminant
par un ''. ». Je confirme !


Là il s'agit plutôt d'un commentaire se terminant par
'#include "foo.h"' :-P


Ça, tu ne sais pas. Il y a peut-être un ' ' qui suit le dernier
'' (et qu'on ne voit pas), et que le commentaire se termine par
" n" :-).

Aussi, je crois qu'une implémentation as aussi le droit de
supprimer les blancs en fin de ligne. Enfin, j'en suis sûr -- il
suffit que l'implémentation définisse son « end of line
indicator » de façon à ce que des blancs finaux en fassent
partie. Techniquement, évidemment, il pourrait aussi en faire
autant pour les , et exiger l'utilisation d'un trigraphe quand
tu veux une ligne de continuation. Mais je crois qu'on serait
tous d'accord en ce qui concerne la qualité (voire même
l'utilisabilité) d'une telle implémentation. Tandis que je crois
que l'autorisation de supprimer les blancs est exprès ; on veut
que le compilateur puisse lire la source en mode texte avec les
entrées/sorties de la bibliothèque. Et « Whether space
characters that are written out immediately before a new-line
character appear when read in is implementation-defined. »

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34