2014-10-19 104 views
6

在很多情况下,我发现我的类需要私有函数来分解它们的功能并重用代码。典型的实现将是:可以在.cpp中声明/定义静态方法吗?

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方法,解决了所有这些问题,但我的问题是,如果我们不希望使用平普尔是否确定了几个功能做这样的事情?

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()); 
} 

在这种情况下,不需要它包括AnotherClass.h在MyClass.h和fooPrivate()不能被任何人称为除了MyClass.cpp内部和声明之后。我对吗?

是否有任何使用此警告的注意事项,或者当我的程序变得更大时,我是否会遇到问题?

+0

在我看来,你的私人成员函数'fooPrivate'本来可以是静态的。否则,你的第二种方法就不能很好地工作。 – 2014-10-19 14:52:39

+0

你知道,'AnotherClass'的前向声明就足够了。这足够轻量。 – Deduplicator 2014-10-19 14:54:04

+0

我了解你。然而,这一点仍然是一样的。即使fooPrivate()使用MyClass的某些成员(这会使其成为非静态的),但在很多情况下,可以使用静态函数来执行某些内容,然后可以使用静态调用的结果来修改此类。 – 2014-10-19 14:57:36

回答

11

实际上,它不仅是好的,我真的会推荐它。

private功能可以被使用,有时必须(访问私有元素时),但是这里有一个问题与他们同在,即使它只是一个声明,他们杂乱的类定义:一个用户班级不应该关心或暴露于班级内部。

另一方面,static函数或函数在源文件中的匿名名称空间中声明是“空闲”的。不管其中有多少你有:

  • 它们不会堆积头
  • Itanium ABI编译器工具链(例如),他们不会导致导出的符号,加快加载时间

但是,如果存在一个缺点,那就是在那些相同的与安腾相关的工具链上,它们缺少名称会导致没有调试符号的错误回溯。尽管如此,这可能会被视为一个小麻烦。

注意:不能直接访问private类的成员很少是一个问题,因为类的方法可以很容易地将对这些成员的引用传递给它们。这意味着当构造函数不公开时,它们不能构建类的实例。

+1

+1的调试评论!这是迄今为止最明确的答案。谢谢你的时间。 – 2014-10-19 15:14:12

+0

你在谈论哪些与itanium相关的工具链? Itanium本身现在完全不相关,不是吗? – 2017-09-11 10:27:25

+1

@avl_sweden:我正在谈论(令人困惑的)[Itanium ABI](https://itanium-cxx-abi.github.io/cxx-abi/),这是Clang,GCC,ICC使用的ABI。 .. – 2017-09-11 12:02:23

6

除了轻微的不便之外,没有任何警告。显然,你的静态函数不会是一个类方法。因此,它只能访问公共类成员和方法。

3

由于你的帮助函数只使用类的公共接口,所以只能使用类实现文件中提供的静态函数。

无论如何,你的例子并不真正需要的AnotherClass的定义,轻便的前瞻性声明,会被罚款:

class AnotherClass; 

另外,我将标志着功能inline在一般原则这两种情况下,当且仅当它仅在实现中使用,并且全部位于同一个翻译单元中:
性能更好/代码更小,并且没有任何缺点的可能性很小。

+1

+1对于'inline' – 2014-10-19 15:02:05

4

我偶尔会这样做,因为“帮助函数”在类的公共接口中几乎没有任何用处。我尝试尽量减少使用这种模式,因为没有访问private变量。但是,免费功能是好的 thing和arguably,甚至increase encapsulation

相关问题