提问人:Adri C.S. 提问时间:5/29/2013 最后编辑:Adri C.S. 更新时间:5/29/2013 访问量:15329
源文件中的私有命名空间
Private namespace in source files
问:
我对私有方法和函数有疑问。 假设我有一些不需要在类中的实用方法。但是这些相同的方法需要调用我不想向用户公开的其他方法。例如:
嫌疑人.h
namespace Suspect {
/**
* \brief This should do this and that and more funny things.
*/
void VerbalKint(void); // This is for you to use
}
嫌疑人.cpp
namespace Suspect {
namespace Surprise {
/**
* \brief The user doesn't need to be aware of this, as long
* the public available VerbalKint does what it should do.
*/
void KeyserSoze(void) {
// Whatever
}
} // end Surprise
void VerbalKint(void) {
Surprise::KeyserSoze();
}
}
因此,此布局有效。当包含 时,只有 是可见的。
这也可以使用类并标记为静态来实现:Suspect.h
VerbalKint
VerbalKint
class Suspect {
public:
// Whatever
static void VerbalKint(void);
private:
static void KeyserSoze(void);
};
我想知道这两种方法之间是否有任何区别。一个比另一个更好(更快、更容易维护)吗?
你有什么想法?
答:
最好的方法是在 中的未命名命名空间中定义所有帮助程序函数,而不是在命名空间中定义。Suspect.cpp
Suspect::Surprise
在您的情况下,这将是:
namespace{
void KeyserSoze(){ ... };
}
您可以简单地从中调用,而无需任何命名空间说明符。KeyserSoze
Suspect.cpp
您可以在此处找到有关此内容的更多信息:未命名/匿名命名空间与静态函数
另一种选择是声明为 ,但标准不建议这样做。C++ 标准在第 7.3.1.1 节“未命名命名空间”第 2 段中写道:KeyserSoze
static
在命名空间范围内声明对象时,不推荐使用 static 关键字,unnamed-namespace 提供了更好的替代方法
评论
static
在 C++11 中未弃用。
实际上,即使当您不在任何标头中声明该函数时,该函数是肉眼不可见的;如果用户编写声明,它仍然可供用户使用。
在 C++ 中,隐藏在文件级别声明的符号的机制是:
static
对于(全局)变量和函数namespace { ... }
(匿名命名空间)用于您想要的任何内容(更通用,更冗长)
例如:
// Suspect.cpp
namespace Suspect {
static void KeyserSore() {}
void VerbalKing() { KeyserSore(); }
}
将某些内容放入类或命名空间之间的主要区别在于,您不能向另一个头文件中的类添加额外的静态函数。
这: 啊
namespace Fred {
void Somefunc();
}
c.I.(英语:c.I)
namespace Fred {
void Anotherfunc();
}
工作,尽管 A 和 B 都不知道对方对他们的命名空间做了什么。可以想象,这可能会导致问题,例如:
C.H.(英语:C.H)
namespace Fred {
void Thirdfunc();
}
D.H.(英语:D.H)
namespace Fred {
bool Thirdfunc();
}
在你开始运行程序之前,这一切都很好,很花花公子......
虽然这并非不可能,但上课的可能性要小得多。
在示例中,如果只有一个源文件,您可能还需要考虑使用匿名命名空间,因为这会将声明限制在文件范围内,因此文件外部的人员无法意外访问它们(或与它们发生冲突)。
评论
如果函数是“free”的,则应在以下位置使用匿名命名空间:*.cpp
namespace Suspect {
namespace Surprise {
namespace {
void KeyserSoze(void) {
// Whatever
}
} // end anon
} // end Surprise
} // end Suspect
甚至:
namespace {
void KeyserSoze(void) {
// Whatever
}
} // end anon
这使它远离客户端,因此他们在链接时无法访问、依赖或与您的导出发生冲突。它还保留了不必要的声明,减少了它们的编译时间,如果定义可见,则可能会减少链接时间或二进制大小。最后,它使它成为私有的,因此他们不能依赖它,你也不需要维护它供他们使用。如果您选择,您仍然可以将这些传递给外部世界(在 的情况下为函数指针)。KeyserSoze()
在其他时候,最好在类中声明一个私有成员函数,然后在(如果可能的情况下)中定义它。通常,当您需要与类建立更密切的关系时(例如,当您需要访问某些成员时),您会选择这种方法。你说问题中不是这样,但我只是重申什么时候应该使用私人成员。*.cpp
评论
KeyserSoze
static
KeyserSoze
KeyserSoze
Suspect
如果它应该是对象类型,则应为类,如果不应是对象类型,则应为命名空间。