web-dev-qa-db-fra.com

Supériorité de l'espace de noms sans nom sur statique?

En quoi les espaces de noms sans nom sont-ils supérieurs au mot clé static?

112
Nawaz

Vous faites essentiellement référence à la section $ 7.3.1.1/2 de la norme C++,

L'utilisation du mot clé statique est déconseillée lors de la déclaration d'objets dans une étendue d'espace de noms; l'espace de noms sans nom offre une alternative supérieure.

L'espace de noms sans nom est supérieur au mot-clé statique, principalement parce que le mot-clé static s'applique uniquement aux déclarations et fonctions variables, pas aux types définis par l'utilisateur.

Le code suivant est valide en C++

   //legal code
   static int sample_function() { /* function body */ }
   static int sample_variable;

Mais ce code n'est PAS valide:

   //illegal code
   static class sample_class { /* class body */ };
   static struct sample_struct { /* struct body */ };

Donc, la solution est, namespace sans nom, qui est la suivante,

   //legal code
   namespace 
   {  
        class sample_class { /* class body */ };
        struct sample_struct { /* struct body */ };
   }

J'espère que cela explique pourquoi unnamed-namespace est supérieur à static.

Notez également que l'utilisation du mot clé statique est déconseillée lors de la déclaration d'objets dans une étendue d'espace de noms (conformément à la norme).

116
Nawaz

Il y a un problème intéressant lié à cela:

Supposons que vous utilisiez le mot clé static ou le nom namespace sans nom pour rendre une fonction interne au module (unité de traduction), car cette fonction est destinée à être utilisée en interne par le module et non accessible en dehors de celui-ci. (Les namespace sans nom ont l'avantage de rendre les définitions de données et de types internes, en plus des fonctions).

Avec le temps, le fichier source de l'implémentation de votre module grandit et vous souhaitez le diviser en plusieurs fichiers source séparés, ce qui permettrait de mieux organiser le code, de trouver les définitions plus rapidement et d'être compilé indépendamment.

Mais maintenant vous êtes confronté à un problème: ces fonctions ne peuvent plus être static pour le module, car static ne se réfère pas réellement au module, mais au - fichier source (unité de traduction). Vous êtes obligé de les rendre non - static pour leur permettre d'accéder à partir d'autres parties (fichiers objets) de ce module. Mais cela signifie également qu'ils ne sont plus cachés/privés pour le module: ayant une liaison externe, ils sont accessibles à partir d'autres modules, ce qui était pas votre intention initiale.

Unnamed namespace ne résoudrait pas ce problème non plus, car il est également défini pour un fichier source particulier (unité de traduction) et n'est pas accessible de l'extérieur.

Ce serait formidable si l'on pouvait spécifier que certains namespace sont private, c'est-à-dire que tout ce qui y est défini est destiné à être utilisé en interne par le module auquel il appartient. Mais bien sûr, C++ n'a pas de concept tel que "modules", seulement "unités de traduction", qui sont étroitement liées aux fichiers source.

6
SasQ

La norme C++ lit à la section 7.3.1.1 Espaces de noms sans nom, paragraphe 2:

L'utilisation du mot clé statique est déconseillée lors de la déclaration d'objets dans une étendue d'espace de noms, l'espace de noms sans nom fournit une alternative supérieure.

Statique s'applique uniquement aux noms d'objets, de fonctions et d'unions anonymes, pas aux déclarations de type.

6
Salgar