web-dev-qa-db-fra.com

C ++: Dois-je utiliser «Typedef» ou «Utilisation d'un espace de nom»?

J'écris une bibliothèque avec des modules dépendants de la part. Lorsque j'inclus un fichier d'un module différent, dois-je résoudre l'espace de noms avec:

using namespace project1::namespace1;
class1 obj;

ou

typedef project1::namespace1::class1 class1;
class1 obj;

Quels sont les avantages/inconvénients de chaque approche? J'ai lu quelque part que nous devrions utiliser typedef in .h fichiers et using in .c dossiers, est-ce conseiller?

Un problème que j'ai rencontré avec 'Typedef' est-il conduit à une ambiguïté de l'espace de noms si j'indique à la fois la classe d'origine et la classe avec "Typedef" dans un troisième module.

40
vid

Les deux options que vous déclarez ne sont pas équivalentes. Celui-ci:

using namespace project1::namespace1;

tirez dans tout de l'espace de noms, vous donnant peu de contrôle et de faire des affrontements susceptibles. Je ne vois que des inconvénients et pas de pros ici.

Mais vous n'avez pas besoin d'utiliser un typedef pour apporter un seul symbole, vous pouvez utiliser

using project1::namespace1::class1;

Que vous utilisiez cela ou le typedef _ ne fait pas trop de différence. Mais gardez à l'esprit que typedef est limité aux types et énumérations, alors que using peut faire référence à des valeurs, fonctions, etc.:

namespace X {
  const int x{42};
  enum Fruit{Apple, Pear};
}

using X::x; // OK
typedef X::x xx; // Error! 'x' in namespace 'X' does not name a type

donc, les deux expressions ne sont pas complètement équivalentes.

75
juanchopanza

Vous ne devez jamais utiliser using ou typedef dans un fichier d'en-tête Juste pour faire des noms plus faciles à taper.

Dans le fichier source, c'est à vous de décider. Il semble être considéré comme une bonne pratique pour écrire tout le nom, car cela indique clairement ce que vous vouliez dire. Si votre espace de noms est trop long, vous pouvez utiliser un alias d'espace de noms pour réduire l'encombrement, mais garder le sens clair: namespace ns = project1::namespace1;

De toute façon, si vous allez importer des symboles dans l'espace de noms global, utilisez using, pas typedef. typedef est utilisé principalement lorsque vous souhaitez appeler le type par un nom différent, plusieurs fois parce que c'est un modèle - par exemple, my_map à la place de std::map<std::string, my_type>, qui est toujours clair, mais beaucoup plus agréable à taper.

Aussi, voir cette question: Pourquoi "utilise" l'espace de noms std "considéré comme une mauvaise pratique?

8
parkovski

La manière la plus claire n'est utilise aucune de ces méthodes - il suffit d'écrire new project1::namespace1::class1().

6
IProblemFactory

utilisez using project1::namespace1::class1

Ou, vous pouvez limiter votre utilisation d'un espace de nom dans une portée locale, à la fois pour votre commodité et non polluez l'espace de noms global.

void function()
{
    using namespace project1::namespace1;

    class1 obj;

    ...
}
3
Lyn