I generally like to organize classes I make into modules by using namespaces, and I also don't go more than 2 namespaces deep but it's still painstakingly hard to fully qualify everything.
I've thought of using using directives but I don't want some headers polluting other headers. For example:
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
The "problem" here is that I can see MyClass1
in MyHeader3.hpp
inside the MyModule2
namespace if I import it inside MyHeader2.hpp
. I can see that this would not be a problem if using directives were allowed at class scope.
Question is, is there a better way of doing this, should I just man up and fully-qualify everything or should I avoid namespaces altogether?
1 Answer 1
No, you should definetely not abandom namespaces! Instead, you should organize your code better, and maybe check your architecture again.
First, you should not use using namespace MyLibrary::MyModule1;
or using MyLibrary::MyModule1::MyClass1;
in a header, to avoid namespace polution, since there is no way to undo that (see this question and answers).
Another option is to use typedefs :
namespace MyLibrary {
namespace MyModule2 {
class MyClass2 {
public:
typedef MyLibrary::MyModule1::MyClass1 FunctionArg;
void DoSomething(FunctionArg parameter);
};
} // namespace MyModule2
} // namespace MyLibrary
And if you use c++11 and later, you can use using
in another way :
namespace MyLibrary {
namespace MyModule2 {
class MyClass2 {
public:
using FunctionArg=MyLibrary::MyModule1::MyClass1;
void DoSomething(FunctionArg parameter);
};
} // namespace MyModule2
} // namespace MyLibrary
-
Doh! I completely forgot about
typedef
-ing inside a class. Exactly (kinda) what I needed. Cheers!John Mark Caguicla– John Mark Caguicla2016年02月09日 16:28:50 +00:00Commented Feb 9, 2016 at 16:28
MyLibrary::
part. Modules, when they finally come, should improve this.using
for type aliases in class scope, and therefore make the aliasprivate
. Theusing namespace ...
is rarely wise and should be avoided. Applying these two rules avoids imported types in your namespace, and still keeps your code fairly easy to read and write.