在许多情况下,我发现我的类需要私有函数来分解它们的功能并重用代码。典型的实现方式是:
MyClass.h
#include "AnotherClass.h"
class MyClass {
public:
float foo() const;
private:
float fooPrivate(const AnotherClass& ac) const;
}
MyClass.cpp
#include "MyClass.h"
float MyClass::foo() const {
return fooPrivate(AnotherClass());
}
float MyClass::fooPrivate(const AnotherClass& ac) const {
return ac.foo();
}
这没关系,但在以下情况下,在头文件中声明fooPrivate()可能会有问题:
我们可能不希望在头文件中包含AnotherClass,如果它仅供内部使用,在MyClass之外不需要。
如果需要许多私有函数,我们冒着使用不必要的私有函数来污染头文件的风险,这些函数会使代码不太清晰,增加编译时间并且更难以维护。
我知道解决所有这些问题的Pimpl习语,但我的问题是如果我们不想使用Pimpl,那么可以为一些函数做这样的事情吗?
MyClass.h
class MyClass {
public:
float foo() const;
}
MyClass.cpp
#include "MyClass.h"
#include "AnotherClass.h"
static float fooPrivate(const AnotherClass& ac) {
return ac.foo();
}
float MyClass::foo() const {
return fooPrivate(AnotherClass());
}
在这种情况下,不需要在MyClass.h中包含AnotherClass.h,除了MyClass.cpp内部以及声明之后,任何人都不能调用fooPrivate()。我是对的吗?
是否有任何警告使用此功能,或者当程序变大时我会遇到问题吗?
答案 0 :(得分:12)
实际上,不仅可以,我实际上会推荐它。
private
函数可以使用,有时必须(访问私有元素时)但是它们有一个问题:即使它只是一个声明,它们使类定义混乱:类的用户不应该关心或暴露给类内部。
另一方面,在源文件中的匿名命名空间中声明的static
函数或函数是" free"。不管你有多少人:
但是,如果存在一个缺点,那就是在那些与Itanium相关的工具链上,如果没有调试符号,它们缺少名称会导致较差的回溯。不过,这可以被视为一个小小的不便。
注意:不能直接访问该类的private
成员很少会出现问题,因为该类的方法可以轻松地将对这些成员的引用传递给它们。这确实意味着当构造函数不公开时,它们无法构建类的实例。
答案 1 :(得分:6)
除了轻微的不便外,没有任何警告。显然,你的静态函数不会是一个类方法。因此,它只能访问公共类成员和方法。
答案 2 :(得分:4)
我偶尔这样做,因为"辅助功能"在课堂的公共界面中几乎没有任何用处。我尝试最小化此模式的使用,因为无法访问private
变量。但是,免费功能是良好的事物,而arguably甚至是increase encapsulation。
答案 3 :(得分:3)
由于你的帮助函数只使用类的公共接口,所以使用只在类implementation-file中可用的静态函数是可以的。
无论如何,你的例子实际上并不需要AnotherClass
的定义,一个轻量级的前向声明就可以了:
class AnotherClass;
另外,在两种情况下,我都会在一般原则上标记函数inline
,如果它仅由实现使用,那么它们都在同一个翻译单元中:
可能会有更好的性能/更小的代码,没有任何缺点。