简体   繁体   English

是否可以仅在.cpp中声明/定义静态方法?

[英]Is it ok to declare/define a static method in the .cpp only?

In many cases I find my classes needing private functions to break down their functionality and reuse code. 在许多情况下,我发现我的类需要私有函数来分解它们的功能并重用代码。 The typical implementation would be : 典型的实现方式是:

MyClass.h MyClass.h

#include "AnotherClass.h"

class MyClass {
public:
    float foo() const;
private:
    float fooPrivate(const AnotherClass& ac) const; 
}

MyClass.cpp MyClass.cpp

#include "MyClass.h"

float MyClass::foo() const {
    return fooPrivate(AnotherClass());
}
float MyClass::fooPrivate(const AnotherClass& ac) const {
    return ac.foo();
}

This is ok, however declaring fooPrivate() in the header file can be problematic in the following cases : 这没关系,但在以下情况下,在头文件中声明fooPrivate()可能会有问题:

  • we might not want to include AnotherClass in the header file if it is only for internal uses and is not needed outside MyClass. 我们可能不希望在头文件中包含AnotherClass,如果它仅供内部使用,并且在MyClass之外不需要。

  • if many private functions are needed we risk polluting the header file with unnecessary private functions that make code less clear, increase compile time and is more difficult to maintain. 如果需要许多私有函数,我们冒着使用不必要的私有函数来污染头文件的风险,这些函数会使代码不太清晰,增加编译时间并且更难以维护。

I am aware of the Pimpl idiom that solves all these problems but my question is if we do not want to use the Pimpl is it ok to do something like this for a few functions ? 我知道解决所有这些问题的Pimpl成语,但我的问题是如果我们不想使用Pimpl是否可以为一些函数做这样的事情?

MyClass.h MyClass.h

class MyClass {
public:
    float foo() const;
}

MyClass.cpp MyClass.cpp

#include "MyClass.h"
#include "AnotherClass.h"

static float fooPrivate(const AnotherClass& ac) {
    return ac.foo();
}
float MyClass::foo() const {
    return fooPrivate(AnotherClass());
}

In this case it is not needed to include AnotherClass.h in MyClass.h and fooPrivate() can not be called by anyone except from inside MyClass.cpp and after it has been declared. 在这种情况下,不需要在MyClass.h中包含AnotherClass.h,除了MyClass.cpp内部以及声明之后,任何人都不能调用fooPrivate()。 Am I right? 我对吗?

Are there any caveats using this or will I end up with problems when my program gets bigger? 是否有任何警告使用这个或当我的程序变大时我会遇到问题吗?

Actually, not only is it okay, I would actually recommend it. 实际上,不仅可以,我实际上会推荐它。

private functions may be used, and sometimes must (when accessing private elements) however there is one issue with them: even if it is only a declaration, they clutter the class definition: a user of the class should not have to care or be exposed to the class internals. private功能可以使用,有时还必须 (访问私有元素时),但是这里有一个问题与他们同在,即使它只是一个声明,他们杂乱的类定义:类的用户应该不会有照顾或暴露到班级内部。

On the other hand, static functions or functions declared in an anonymous namespace within a source file are "free". 另一方面,在源文件中的匿名命名空间中声明的static函数或函数是“空闲的”。 No matter how many of them you have: 不管你有多少人:

  • they do not clutter the header 它们不会使标题混乱
  • on Itanium ABI compiler tool-chains (for example), they do not lead to an exported symbol, speeding up load time Itanium ABI编译器工具链(例如)上,它们不会导致导出符号,从而加快了加载时间

If there is one downside, though, it is that on those same Itanium-related tool-chains their absence of name make for poor backtraces without debug symbols. 但是,如果存在一个缺点,那就是在那些与Itanium相关的工具链上,如果没有调试符号,它们缺少名称会导致较差的回溯。 It can be seen as a minor inconvenience though. 但是,它可以被视为轻微的不便。

Note: not having access directly to private members of the class is rarely an issue because a method of the class can easily pass a reference to those members to them. 注意:没有直接访问类的private成员很少是一个问题,因为类的方法可以很容易地将对这些成员的引用传递给它们。 It does mean they cannot build an instance of the class when the constructors are not public however. 它确实意味着当构造函数不公开时,它们无法构建类的实例。

There are no caveats, except slight inconvenience. 除了轻微的不便之外,没有任何警告。 Your static function is not going to be a class method, obviously. 显然,你的静态函数不会是一个类方法。 Because of that, it can only access public class members and methods. 因此,它只能访问公共类成员和方法。

I do this occasionally, for "helper functions" that have literally no use whatsoever in the class's public interface. 我偶尔这样做,因为“帮助函数”在类的公共接口中几乎没有任何用处。 I try to minimise the use of this pattern as there is no access to private variables. 我尝试最小化这种模式的使用,因为无法访问private变量。 However, free functions are a good thing and arguably even increase encapsulation . 然而,免费的功能是一件好事可以说甚至增加封装

As your helper-function does only use the public interface of the class, using a static function only available in the classes implementation-file is fine. 由于你的辅助函数只使用类的公共接口,所以使用只在类implementation-file中可用的静态函数是可以的。

Anyway, your example did not actually need the definition of AnotherClass , a lightweight forward-declaration would have been fine: 无论如何,你的例子实际上并不需要AnotherClass的定义,一个轻量级的前向声明就可以了:

class AnotherClass;

Also, I would mark the function inline in both cases on general principles, iff it is used only by the implementation, and that is all together in the same translation-unit: 另外,我将标志着该功能inline在一般原则这两种情况下,当且仅当它是由实现只使用,这是所有在同一个翻译单元:
There would be a slight chance of better performance / smaller code, without any downsides. 可能会有更好的性能/更小的代码,没有任何缺点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM