我对私人方法有疑问功能。 假设我有一些不必在类中的实用方法。但是那些相同的方法需要调用我不想向用户公开的其他方法。例如:
Suspect.h
namespace Suspect {
/**
* \brief This should do this and that and more funny things.
*/
void VerbalKint(void); // This is for you to use
}
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();
}
}
所以,这种布局有效。包含Suspect.h
时,只有VerbalKint
可见。
这可以通过使用类并将VerbalKint
标记为静态来实现:
class Suspect {
public:
// Whatever
static void VerbalKint(void);
private:
static void KeyserSoze(void);
};
我想知道这两种方法之间是否存在任何差异。一个比另一个更好(更快,更容易维护)吗?
你有什么想法?
答案 0 :(得分:9)
最好的方法是在Suspect.cpp
中的未命名命名空间中定义所有辅助函数,而不是在Suspect::Surprise
命名空间中。
在您的情况下,这将是:
namespace{
void KeyserSoze(){ ... };
}
您只需在KeyserSoze
内调用Suspect.cpp
而无需任何名称空间说明符。
您可以在此处找到有关此内容的更多信息:Unnamed/anonymous namespaces vs. static functions
另一种方法是将KeyserSoze
声明为static
,但标准不建议这样做。 C ++标准在第7.3.1.1节“未命名的命名空间”中进行了介绍,第2段:
在声明命名空间作用域中的对象时,不推荐使用static关键字,unnamed-namespace提供了一个更好的替代方法
答案 1 :(得分:7)
如果函数是“空闲的”,则应在*.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
中定义它(如果可能)。通常,当您需要与班级建立更密切的关系时(例如,当您需要访问某些成员时),您会选择此方法。你说问题并非如此,但我只是重申应该使用私人成员。
答案 2 :(得分:5)
实际上,即使在未在任何标题中声明该功能时,该功能仍然不可见;如果他们写下声明,它仍然可供用户使用。
在C ++中,隐藏在文件级别声明的符号的机制是:
static
用于(全局)变量和函数namespace { ... }
(匿名命名空间),用于任何你想要的东西(更一般,更详细)例如:
// Suspect.cpp
namespace Suspect {
static void KeyserSore() {}
void VerbalKing() { KeyserSore(); }
}
答案 3 :(得分:2)
在类或命名空间中放置内容之间的主要区别在于,您无法在另一个头文件中的类中添加额外的静态函数。
此: A.H
namespace Fred {
void Somefunc();
}
b.h
namespace Fred {
void Anotherfunc();
}
工作,虽然a和b都不知道彼此对其命名空间做了什么。这可能会导致问题,例如:
c.h
namespace Fred {
void Thirdfunc();
}
d.h
namespace Fred {
bool Thirdfunc();
}
这一切都很好,花花公子,直到你开始运行程序......
这虽然并非不可能,但课程的可能性要小得多。
在您的示例中,只有一个源文件,您可能还需要考虑使用匿名命名空间,因为这会将声明限制为文件范围,因此文件外的人无法访问它们(或与它们发生冲突)事故。