私は通常、名前空間を使用して、作成するクラスをmodulesで整理するのが好きです。また、名前空間の深さは2を超えませんが、すべてを完全に修飾することは依然として困難です。
singディレクティブを使用することを考えましたが、一部のヘッダーが他のヘッダーを汚染したくありません。例えば:
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
ここでの「問題」は、MyClass1
内にインポートすると、MyHeader3.hpp
名前空間内のMyModule2
内にMyHeader2.hpp
が表示されることです。 singディレクティブがクラススコープで許可されている場合、これは問題にならないことがわかります。
質問は、これを行うより良い方法はありますか?私はすべてを完全に修飾し、名前空間を完全に避けるべきですか?
いいえ、明確に名前空間を放棄するべきではありません!代わりに、コードを適切に整理し、おそらくアーキテクチャを再度確認する必要があります。
まず、using namespace MyLibrary::MyModule1;
またはusing MyLibrary::MyModule1::MyClass1;
ヘッダーで、名前空間の汚染を回避するため。ヘッダーを元に戻す方法はありません( この質問と回答 を参照)。
別のオプションはtypedefsを使用することです:
namespace MyLibrary {
namespace MyModule2 {
class MyClass2 {
public:
typedef MyLibrary::MyModule1::MyClass1 FunctionArg;
void DoSomething(FunctionArg parameter);
};
} // namespace MyModule2
} // namespace MyLibrary
また、c ++ 11以降を使用している場合は、using
を別の方法で使用できます。
namespace MyLibrary {
namespace MyModule2 {
class MyClass2 {
public:
using FunctionArg=MyLibrary::MyModule1::MyClass1;
void DoSomething(FunctionArg parameter);
};
} // namespace MyModule2
} // namespace MyLibrary