我对私人方法和功能有疑问.假设我有一些不必在类中的实用方法.但是那些相同的方法需要调用我不想向用户公开的其他方法.例如:
Suspect.h
namespace Suspect {
/**
* \brief This should do this and that and more funny things.
*/
void VerbalKint(void); // This is for you to use
}
Run Code Online (Sandbox Code Playgroud)
Suspect.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();
}
}
Run Code Online (Sandbox Code Playgroud)
所以,这种布局是有效的.包含时Suspect.h,只有VerbalKint可见.这可以使用类和标记VerbalKint为静态来实现:
class Suspect {
public:
// Whatever
static void VerbalKint(void);
private:
static void KeyserSoze(void);
};
Run Code Online (Sandbox Code Playgroud)
我想知道这两种方法之间是否存在任何差异.一个比另一个更好(更快,更容易维护)吗?
你的想法是什么?
最好的方法是在未命名的命名空间中定义所有辅助函数Suspect.cpp,而不是在Suspect::Surprise命名空间中.
在您的情况下,这将是:
namespace{
void KeyserSoze(){ ... };
}
Run Code Online (Sandbox Code Playgroud)
您可以简单地KeyserSoze从内部调用没有任何名称空间说明符Suspect.cpp.
您可以在此处找到有关此内容的更多信息:未命名/匿名命名空间与静态功能
另一种方法是宣布KeyserSoze要static,但这不是由标准的建议.C++标准在第7.3.1.1节"未命名的命名空间"中进行了介绍,第2段:
在声明命名空间作用域中的对象时,不推荐使用static关键字,unnamed-namespace提供了一个更好的替代方法
如果函数是"空闲的",则应在以下位置使用匿名命名空间*.cpp:
namespace Suspect {
namespace Surprise {
namespace {
void KeyserSoze(void) {
// Whatever
}
} // end anon
} // end Surprise
} // end Suspect
Run Code Online (Sandbox Code Playgroud)
甚至:
namespace {
void KeyserSoze(void) {
// Whatever
}
} // end anon
Run Code Online (Sandbox Code Playgroud)
这使它远离客户端,因此在链接时他们无法访问,依赖或碰撞您的导出.如果定义可见,它还会保留不必要的声明,减少编译时间和可能的链接时间或二进制大小.最后,它使它成为私有的,因此它们不能依赖它,你不需要维护它以供它们使用.如果你选择的话,你仍然可以把它们传递到外面的世界(在KeyserSoze()情况下是函数指针).
在其他时候,最好在你的类中声明一个私有成员函数,然后在*.cpp(如果可能的话)中定义它.通常,当您需要与班级建立更密切的关系时(例如,当您需要访问某些成员时),您会选择此方法.你说这不是问题的情况,但我只是重申应该使用私人成员.
实际上,即使你没有在任何标题中声明它,该功能是不可见的; 如果他们写下声明,它仍然可供用户使用.
在C++中,隐藏在文件级别声明的符号的机制是:
static for(全局)变量和函数namespace { ... } (匿名命名空间)任何你想要的东西(更一般,更详细)例如:
// Suspect.cpp
namespace Suspect {
static void KeyserSore() {}
void VerbalKing() { KeyserSore(); }
}
Run Code Online (Sandbox Code Playgroud)