简体   繁体   English

C++ 私有函数真的需要在头文件中吗?

[英]Do C++ private functions really need to be in the header file?

I have always thought of header files as a sort of 'public interface' describing a class, in which case it would be better to keep private fields and functions in the .cpp file.我一直认为头文件是一种描述类的“公共接口”,在这种情况下,最好将私有字段和函数保留在 .cpp 文件中。

I understand that private fields need to be in the header so that other classes can tell how much memory an instance of a class will consume, but it occurred to me as I was about to write a private helper function, that this function could be made static, in which case there was no need for it to be 'part of the class' at all, it could just as easily be a regular function in the class definition's .cpp file.我知道私有字段需要在标头中,以便其他类可以知道一个类的实例将消耗多少内存,但是当我即将编写一个私有帮助函数时,我突然想到,可以制作这个函数static,在这种情况下,它根本不需要成为“类的一部分”,它可以很容易地成为类定义的 .cpp 文件中的常规函数​​。

It then occurred to me that all private functions could potentially be rewritten to be static by accepting pointers/references to class fields instead of expecting to be defined in the class.然后我想到,通过接受对类字段的指针/引用而不是期望在类中定义,所有私有函数都可能被重写为静态的。

This would eliminate the need to declare any private functions in the header file.这将消除在头文件中声明任何私有函数的需要。

I do like to follow conventions, so is it considered an established convention in C++, that non-static private functions should be in the header file?我确实喜欢遵循约定,所以它是否被认为是 C++ 中的既定约定,非静态私有函数应该在头文件中? What about static functions or static constants?静态函数或静态常量呢?

I'm going to put in some code to explain what I'm getting at:我将输入一些代码来解释我的意思:

.h file: .h 文件:

#ifndef SOME_CLASS_H
#define SOME_CLASS_H

class SomeClass
{
private:
    int x;
public:
    void combineWithX(int y);
};

#endif

.cpp file .cpp 文件

#include "SomeClass.h"

void someHelper(int* x)
{
    *x = (*x) + 1;
}

void SomeClass::combineWithX(int y)
{
    someHelper(&x);
    x += y;
}

Note that someHelper(int* x) in the .cpp file references the private member x in spirit, but not directly, and therefore does not need to appear in the header.请注意,.cpp 文件中的someHelper(int* x)在精神上引用了私有成员 x,但不是直接引用,因此不需要出现在 header 中。 I'm wondering if this sort of thing is considered 'bad style'.我想知道这种事情是否被认为是“坏风格”。

Private helper functions can be hidden from the public header file by moving them to an inner class.通过将私有帮助函数移动到内部类,可以从公共头文件中隐藏它们。 This works because the inner class is considered part of the class and can access the surrounding class's private members.这是因为内部类被认为是类的一部分并且可以访问周围类的私有成员。

Unlike the PIMPL idiom, this does not have any dynamic allocation or indirection penalty.PIMPL习语不同,这没有任何动态分配或间接惩罚。 Compile times should be faster when editing/refactoring private functions, as there isn't any need to recompile all the files, including the public header.编辑/重构私有函数时编译时间应该更快,因为不需要重新编译所有文件,包括公共头文件。

Example:例子:

public .h file公共 .h 文件

#ifndef SOME_CLASS_H
#define SOME_CLASS_H

class SomeClass
{
private:
    // Just forward declaring in public header.
    struct Private;
    int x;
public:
    void combineWithX(int y);
};

#endif

in .cpp file在 .cpp 文件中

#include "SomeClass.h"

// Declare all private member functions of SomeClass here
struct SomeClass::Private
{
  static void someHelper(SomeClass& self)
  {
    self.x = self.x + 1;
  }
};

void SomeClass::combineWithX(int y)
{
    Private::someHelper(*this);
    x += y;
}

I agree that it is a problem that implementation details need to be exposed in a header file;我同意需要在头文件中公开实现细节是一个问题; it interferes with separation of interface and implementation.它干扰了接口和实现的分离。

Moving private helper functions to be free functions in the .cpp file (I presume that is what you meant by "static") won't work if those functions need to access private member variables.如果这些函数需要访问私有成员变量,则将私有辅助函数移动为.cpp文件中的自由函数(我认为这就是您所说的“静态”)将不起作用。

You may be interested to look at the pImpl idiom (more)您可能有兴趣查看pImpl 成语(更多)

Sometimes I see people using two different headers, a public header and a private one, like this:有时我看到人们使用两个不同的标头,一个公共标头和一个私有标头,如下所示:

// SomeClass.h - - - -   

SomeClass 
{
public:
   // public functions    
}

// SomeClass_.h - - - -

SomeClass
{
public:
    // public functions
private:
    // private functions
}

// SomeClass.cpp - - - -

#include "SomeClass_.h"

// SomeClass implementation

This has the advantage of a public header that isn't cluttered with private function declarations, but it requires the developer to maintain 3 copies of each function signature.这具有公共标头的优点,它不会与私有函数声明杂乱无章,但它需要开发人员维护每个函数签名的 3 个副本。

Header files have long been recognized by many as being problematic in general, not only because of the added maintenance overhead associated with them, but also because of the effect they have on the build environment.长期以来,头文件通常被许多人认为是有问题的,这不仅是因为与它们相关的额外维护开销,还因为它们对构建环境的影响。 It's easy to write code or set build settings that cause a cascade of system or external headers to fail to compile, resulting in a large number of potentially obscure errors.编写代码或设置构建设置很容易导致一系列系统或外部头文件无法编译,从而导致大量潜在的模糊错误。 C++20 Modules are an alternative that may be worth exploring. C++20 模块是一个值得探索的替代方案。

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

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