繁体   English   中英

C++中使用static非成员函数的原因和意义是什么?

[英]What is the reason and the meaning to use static non-member functions in C++?

我想知道在C++中使用static非成员函数是什么意思

以及为什么人们会使用那些而不是非 static 的。

作为参考,我正在阅读这个问题其他网站上的这个问题,上面写着

这意味着你不能从另一个cpp文件中调用它

在我的情况下,我有一个.h文件和一个“主”cpp 文件。 我在 h 文件中实现了一个 function 作为 static 和非静态非成员,我可以从 cpp 文件中调用它,结果没有变化

所以我想知道 static 为什么以及有什么区别或效果

注意:请注意,本题涉及static在:

  • C
  • 成员函数
  • 变量

当链接整个程序和从多个地方调用函数时,就会看到差异。

如果foo.cppbar.cpp都包含implementation.h ,带有static int baz() { return 0; } static int baz() { return 0; } ,方法baz将独立存在于foo.cppbar.cpp的编译单元中。

当方法是非静态(和非内联)时,方法baz被认为可由知道原型的所有编译单元链接。 在这种情况下编译gcc foo.cpp bar.cpp将导致baz的多个引用的链接错误。

在大多数 C++ 实现中,每个.cpp文件都被编译成对应的.o文件。 .o文件包含.cpp文件功能的object 代码——即 CPU 需要执行以执行这些功能的机器代码指令。

对于非静态函数, .o文件还包含链接器可读的元数据; .o文件中存在的(损坏的)function 名称列表,这些函数位于文件中等。在链接时,linker 将使用此元数据来解析对这些函数的调用,这些函数是从在其他.cpp文件中。

对于 static 函数,OTOH, .o文件包含任何元数据; 就linker而言,static功能不存在。 static 函数实际上是“秘密的”,仅可用于同一.cpp文件中的其他代码(它不依赖于 linker 来访问 static 函数,因为它是作为同一编译单元的一部分编译的,并且可以因此直接引用它们)

在您的情况下,您在.h文件中实现了 static function,这意味着 function 的单独副本包含在使用该 function 的每个.cpp文件的.o文件中,这就是为什么它仍然“有效”的原因你。

人们经常使用static作为一种私有命名空间标记,以保证不会从它们出现的.cpp文件外部调用函数。在 C++ 中,可以使用匿名命名空间来实现类似的结果。

正如其他人解释的那样,在 C++ 中,如果您的代码包含多个文件,那么默认情况下所有全局函数和变量都具有external linking 例如在文件A.cpp 中定义的A.cpp可以通过编译器自动链接在文件B.cpp中调用。 请记住,您必须分别编译这两个文件,稍后您将告诉编译器链接这些对象.o文件。 编译器会将所有内容拼接在一起。 正如我在下面的Makefile中所做的那样。

但是如果你想禁用external linking ,你将使你的 function 成为static所以现在你的 function 或变量仅可用于声明它的文件。 这称为internal linking

内部链接用于你必须有全局变量的地方,但你不希望你的全局变量在这个文件之外被访问,而其他一些文件意外地修改了它。

为了更好地理解这个代码是如何工作的:

第一个.cpp

#include <iostream>
/*static*/ void hello(){ //static will not let this code compile
    std::cout << "Hello I am external linking" << std::endl;
}

主.cpp

void hello();
int main(){
    hello();
}

Makefile

program: first.o main.o
    g++ main.o first.o -o test

main.o: main.cpp
    g++ -g -c main.cpp -o main.o


first.o: first.cpp
    g++ -g -c first.cpp -o first.o

这按您预期的那样工作。 但是如果你把static放在 first.cpp 中hello()first.cpp ,这将变成内部链接,所以你会得到编译器的链接错误。

暂无
暂无

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

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