J'aime généralement organiser les classes que je transforme en modules en utilisant des espaces de noms, et je ne vais pas plus de 2 espaces de noms en profondeur, mais il est toujours très difficile de tout qualifier.
J'ai pensé à utiliser les directives sing mais je ne veux pas que certains en-têtes polluent les autres en-têtes. Par exemple:
MyHeader1.hpp
namespace MyLibrary {
namespace MyModule1 {
class MyClass1 {
// stuff
};
} // namespace MyModule1
} // namespace MyLibrary
MyHeader2.hpp
namespace MyLibrary {
namespace MyModule2 {
// I can import stuff
// using namespace MyLibrary::MyModule1;
// using MyLibrary::MyModule1::MyClass1;
class MyClass2 {
public:
void DoSomething(MyLibrary::MyModule1::MyClass1 parameter); // I could do this
void DoSomething(MyClass1 parameter); // or this (easier)
};
} // namespace MyModule2
} // namespace MyLibrary
MyHeader3.hpp
#include <MyModule2/MyHeader2.hpp>
namespace MyLibrary {
namespace MyModule2 {
// I understand that MyClass3 may use MyClass1 from here (the using directive would be beneficial), but what if it doesn't; it's left hanging in here import-ed
// I can see MyLibrary::MyModule1::MyClass1 from here!
class MyClass3 {
MyClass2 some_var;
};
} // namespace MyModule 2
} // namespace MyLibrary
Le "problème" ici est que je peux voir MyClass1
dans MyHeader3.hpp
à l'intérieur de MyModule2
namespace si je l'importe dans MyHeader2.hpp
. Je peux voir que ce ne serait pas un problème si les directives sing étaient autorisées au niveau de la classe.
La question est, existe-t-il une meilleure façon de le faire, dois-je simplement tout mettre en place et tout qualifier ou dois-je éviter complètement les espaces de noms?
Non, vous ne devez absolument pas abandonner les espaces de noms! Au lieu de cela, vous devriez mieux organiser votre code et peut-être vérifier à nouveau votre architecture.
Tout d'abord, vous ne devez pas utiliser using namespace MyLibrary::MyModule1;
ou using MyLibrary::MyModule1::MyClass1;
dans un en-tête, pour éviter la pollution de l'espace de noms, car il n'y a aucun moyen de l'annuler (voir cette question et réponses ).
Une autre option consiste à utiliser des typedefs:
namespace MyLibrary {
namespace MyModule2 {
class MyClass2 {
public:
typedef MyLibrary::MyModule1::MyClass1 FunctionArg;
void DoSomething(FunctionArg parameter);
};
} // namespace MyModule2
} // namespace MyLibrary
Et si vous utilisez c ++ 11 et versions ultérieures, vous pouvez utiliser using
d'une autre manière:
namespace MyLibrary {
namespace MyModule2 {
class MyClass2 {
public:
using FunctionArg=MyLibrary::MyModule1::MyClass1;
void DoSomething(FunctionArg parameter);
};
} // namespace MyModule2
} // namespace MyLibrary