对于我的库,我想公开一个干净的公共API,它不会分散实现细节.但是,正如你所知,这些细节甚至泄漏到了公共领域:有些类具有库的其余部分使用的有效公共方法,但对API的用户来说并不是非常有用,因此需要成为它的一部分.公共代码的简化示例:
class Cookie;
class CookieJar {
public:
Cookie getCookie();
}
class CookieMonster {
public:
void feed(CookieJar cookieJar) {
while (isHungry()) {
cookieJar.getCookie();
}
}
bool isHungry();
}
Run Code Online (Sandbox Code Playgroud)
a的getCookie()
方法CookieJar
对于库的用户没用,他们可能不喜欢cookie.然而CookieMonster
,当给出它时,它被用于喂养它自己.
有一些成语有助于解决这个问题.Pimpl习语提供隐藏类的私有成员,但几乎不掩饰不应该成为API一部分的公共方法.也可以将它们移动到实现类中,但是您需要提供对它的直接访问以供库的其余部分使用.这样的标题看起来像这样:
class Cookie;
class CookieJarImpl;
class CookieJar {
public:
CookieJarImpl* getImplementation() {
return pimpl.get();
}
private:
std::unique_ptr<CookieJarImpl> pimpl;
}
Run Code Online (Sandbox Code Playgroud)
如果你真的需要阻止用户访问这些方法,这很方便,但如果它只是一个烦恼,这没有多大帮助.实际上,新方法现在比上一个方法更无用,因为用户无权访问实现CookieJarImpl
.
另一种方法是将接口定义为抽象基类.这可以明确控制公共API的一部分.任何私有细节都可以包含在此界面的实现中,这是用户无法访问的.需要注意的是,由此产生的虚拟调用会影响性能,甚至比Pimpl成语更具影响力.更清洁的API的交易速度对于应该是高性能库而言并不是很有吸引力.
为了详尽无遗,另一种选择是将有问题的方法设为私有,并在需要的地方使用朋友类从外部访问它们.但是,这使得目标对象也可以访问真正的私有成员,这有点破坏了封装.
到目前为止,对我来说最好的解决方案似乎是Python方式:不要试图隐藏实现细节,只需恰当地命名它们,这样它们很容易识别为不是公共API的一部分,也不会分散常规用法的注意力.想到的命名约定是使用下划线前缀,但显然这些名称是为编译器保留的,不鼓励使用它们.
是否有任何其他c ++命名约定用于区分不打算从库外使用的成员?或者你会建议我使用上面的替代品之一或我错过的其他东西?