C++中的命名空间
答
命名空间指令的声明类型在您的代码作用域中引入了选定的命名符号(并且在没有命名空间限定符的情况下使来自同一名称空间的其他符号无法访问)。
命名空间指令的使用类型将名称空间中的所有符号引入到代码范围内 - 这意味着您不一定确切知道引入了哪些符号(可能有未记录的符号或先前遗留的符号该库的版本,或...)。
- 对于控件,使用声明类型的命名空间指令。
- 为了方便(有风险),使用using类型的命名空间指令。
答
除了使用声明允许访问符号而不是命名空间外,using声明还将符号带入声明的范围。 using指令只影响查找。
答
Jonathan已经恢复using namespace foo;
和using foo::Bar;
之间的差异,但我认为他的答案很不完整。
第一个:using namespace
应该永远不会出现在头文件中。通过这样做,你可能会使它不可能与其他头文件结合使用,因为符号冲突...
第二:一般来说,你应该尽量限制符号的范围,尽可能地已经做一边写代码:
for (size_t i = 0; i < 5; ++i)
{
std::string myString = myVec.at(i);
if (myString == "Foo") { std::cout << "Found"; break; }
}
这将是无用的(和污染)有声明的for
循环外myString
。事实上,这个建议可以在许多书中找到:
From Scott Meyers'Effective C++,Item 26:尽可能推迟变量定义。
从香草萨特和安德烈Alexandrescu的的C++ Coding Standard,项目18:变量声明为本地尽可能
没有理由不这样做与using
声明。
第三:考虑using
的替代方案:名称空间别名和typedef
。
// foo.h
class Foo
{
public:
std::vector<std::string> getSynonyms(const std::string& s) const;
private:
typedef std::map< std::string, std::vector<std::string> > synonyms_type;
synonyms_type mSynonyms;
};
// foo.cpp (never in header, at general scope)
namespace fu = boost::fusion;
std::vector<std::string> Foo::getSynonyms(const std::string& s) const
{
synonyms_type::const_iterator it =
std::find(mSynonyms.begin(), mSynonyms.end(), s);
std::vector<std::string> result;
if (it != mSynonyms.end()) { result = it->second; }
return result;
}
有什么优点?
- 命名空间走样>键入减少几乎一样多,而不注入类型在当前范围权利,使没有风险
- 的typedef>键入减少超过
using
,并允许基础类型的易变化太大。
它还调整访问权限。 – Potatoswatter 2010-04-04 02:37:23