C++,私有函数真的需要在 header 文件中吗?
C++, do private functions really need to be in the header file?
我一直认为 header 文件是一种描述 class 的 'public interface',在这种情况下最好将私有字段和函数保留在 cpp 文件中.
我知道私有字段需要在 header 中,以便其他 classes 可以知道 class 的实例将消耗多少内存,但它发生了当我正要编写一个私有辅助函数时,我知道这个函数可以是静态的,在这种情况下根本不需要它是 'part of the class',它可以很容易地成为class 定义的 .cpp 文件。
然后我想到 all 私有函数可能 re-written 通过接受 [=47] 是静态的=] 到 class 字段,而不是期望在 class.
中定义
这将消除在 header 文件中声明任何私有函数的需要。
我确实喜欢遵循约定,所以现在我想问一下,non-static 私有函数 应该[=38= 是否被认为是 C++ 中的既定约定] 在 header 文件中?静态函数或静态常量呢?
编辑:我将放入一些代码来解释我的意思:
.h 文件:
#ifndef SOME_CLASS_H
#define SOME_CLASS_H
class SomeClass
{
private:
int x;
public:
void combineWithX(int y);
};
#endif
.cpp 文件
#include "SomeClass.h"
void someHelper(int* x)
{
*x = (*x) + 1;
}
void SomeClass::combineWithX(int y)
{
someHelper(&x);
x += y;
}
请注意,cpp 文件中的 someHelper(int* x)
实质上引用了私有成员 x,但不是直接引用,因此不需要出现在 header 中。我想知道这种事情是否被认为是 'bad style'
我同意需要在头文件中公开实现细节是一个问题;它干扰了接口和实现的分离。
如果这些函数需要访问私有成员变量,则将私有辅助函数移动为 .cpp
文件中的自由函数(我想这就是您所说的 "static" 的意思)将不起作用。
您可能有兴趣查看 pImpl idiom (more)
私有辅助函数可以从 public 头文件中隐藏,方法是将它们移动到内部 class。这是可行的,因为内部 class 被认为是 class 的一部分并且可以访问周围 class 的私有成员。
与 PImpl 习惯用法不同,它没有任何动态分配或间接惩罚。 editing/refactoring 私有函数的编译时间应该更快,因为不需要重新编译所有文件,包括 public 头文件。
示例:
public.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
在 .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;
}
怎么样
// MyClass.h -
MyClass {
public:
// public stuff..
#ifdef mynamespace_myclass_p
private:
// private stuff..
#endif // mynamespace_myclass_p
}
// MyClass.cpp -
#define mynamespace_myclass_p
#include "MyClass.h"
// implementation code..
嗯,但是你的 headers 仍然堆满了私人物品。
Headers 太痛苦了。我可能是错的,但目前我觉得 headers 是所有 C++ 中痛苦/有用比率最大的东西。当你用 C++ 编程时,你基本上必须在至少两个地方维护你所有的方法签名,如果你不希望你的 public headers 被私有的东西弄得乱七八糟,你几乎必须有 2 headers 的版本,这意味着至少在 3 个地方保留您的签名!再加上任何被证明是需要的前锋声明。说真的,它们带来的麻烦远远超过它们的价值。
我真的很期待看到 C++20 的模块系统如何发挥作用。这可能是一个巨大的福音。我们已经等了将近 5 年了。
我一直认为 header 文件是一种描述 class 的 'public interface',在这种情况下最好将私有字段和函数保留在 cpp 文件中.
我知道私有字段需要在 header 中,以便其他 classes 可以知道 class 的实例将消耗多少内存,但它发生了当我正要编写一个私有辅助函数时,我知道这个函数可以是静态的,在这种情况下根本不需要它是 'part of the class',它可以很容易地成为class 定义的 .cpp 文件。
然后我想到 all 私有函数可能 re-written 通过接受 [=47] 是静态的=] 到 class 字段,而不是期望在 class.
中定义这将消除在 header 文件中声明任何私有函数的需要。
我确实喜欢遵循约定,所以现在我想问一下,non-static 私有函数 应该[=38= 是否被认为是 C++ 中的既定约定] 在 header 文件中?静态函数或静态常量呢?
编辑:我将放入一些代码来解释我的意思:
.h 文件:
#ifndef SOME_CLASS_H
#define SOME_CLASS_H
class SomeClass
{
private:
int x;
public:
void combineWithX(int y);
};
#endif
.cpp 文件
#include "SomeClass.h"
void someHelper(int* x)
{
*x = (*x) + 1;
}
void SomeClass::combineWithX(int y)
{
someHelper(&x);
x += y;
}
请注意,cpp 文件中的 someHelper(int* x)
实质上引用了私有成员 x,但不是直接引用,因此不需要出现在 header 中。我想知道这种事情是否被认为是 'bad style'
我同意需要在头文件中公开实现细节是一个问题;它干扰了接口和实现的分离。
如果这些函数需要访问私有成员变量,则将私有辅助函数移动为 .cpp
文件中的自由函数(我想这就是您所说的 "static" 的意思)将不起作用。
您可能有兴趣查看 pImpl idiom (more)
私有辅助函数可以从 public 头文件中隐藏,方法是将它们移动到内部 class。这是可行的,因为内部 class 被认为是 class 的一部分并且可以访问周围 class 的私有成员。
与 PImpl 习惯用法不同,它没有任何动态分配或间接惩罚。 editing/refactoring 私有函数的编译时间应该更快,因为不需要重新编译所有文件,包括 public 头文件。
示例:
public.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
在 .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;
}
怎么样
// MyClass.h -
MyClass {
public:
// public stuff..
#ifdef mynamespace_myclass_p
private:
// private stuff..
#endif // mynamespace_myclass_p
}
// MyClass.cpp -
#define mynamespace_myclass_p
#include "MyClass.h"
// implementation code..
嗯,但是你的 headers 仍然堆满了私人物品。
Headers 太痛苦了。我可能是错的,但目前我觉得 headers 是所有 C++ 中痛苦/有用比率最大的东西。当你用 C++ 编程时,你基本上必须在至少两个地方维护你所有的方法签名,如果你不希望你的 public headers 被私有的东西弄得乱七八糟,你几乎必须有 2 headers 的版本,这意味着至少在 3 个地方保留您的签名!再加上任何被证明是需要的前锋声明。说真的,它们带来的麻烦远远超过它们的价值。
我真的很期待看到 C++20 的模块系统如何发挥作用。这可能是一个巨大的福音。我们已经等了将近 5 年了。