问题描述
在工作中,我看到很多 ObjC++ 文件在顶部都有几十个静态 C 辅助函数。我想将这些静态 C 辅助函数分解为一个单独的文件,然后只导入标头以提高可读性。
代替:
static int _AddEm(const int a,const int b) { return a + b }
...
...
...
x 300
类似于:
#import "MyClassHelpers.h"
那将包含所有静态 C 辅助函数。问题是 static 似乎只在声明的文件中工作(我来自 Swift 和 Java 背景),所以我不能只在 C++ 世界中声明一个静态类并带来它,它的助手就结束了。我想保持使用静态的速度和二进制大小的好处。这方面的最佳做法是什么?
谢谢!
解决方法
在 C 中,将 static
放在函数上意味着该函数仅限于声明它的文件。 (因此,您可以在多个文件中使用相同名称的 static
函数而不会发生冲突,而没有 static
链接器可能会抱怨多个具有相同名称的函数。)在某种程度上,您可以将其视为使函数对文件“私有”(在您可能熟悉的面向对象语言中类的私有成员的意义上)。
如果你想定义一个函数的代码一次并在多个文件中使用它,你想要相反的——让它not static
,然后在中声明函数签名带有 extern
的标题,如下所示:
// in MyClassHelpers.h
extern int _AddEm(const int a,const int b);
// in MyClassHelpers.c
int _AddEm(const int a,const int b) { return a + b }
这样,包含 MyClassHelpers.h
的其他文件可以使用此函数,链接器会将它与从 MyClassHelpers.c
编译的单个实现链接。
如果您在标题中放置了 static
函数定义,如下所示:
// in MyClassHelpers.h
static int _AddEm(const int a,const int b) { return a + b }
那么每个包含这个头文件的实现文件都会有效地拥有它自己的这个函数的“私有”副本,这可能会导致相同的代码被重复多次。 (包含头文件与将头文件的内容复制粘贴到包含它的文件中基本相同,因此如果您在每个文件中都编写了此静态函数定义。)
我突然想到,也许您试图对这些小函数做的是让对它们的调用内联,而不是作为单独的函数调用进行调用。在这种情况下,也许在标题中声明它 static
和 inline
会起作用:
// in MyClassHelpers.h
static inline int _AddEm(const int a,const int b) { return a + b }