如何将 cpp 文件中的静态函数公开给其他文件

How to expose static function in a cpp file to other files

本文关键字:文件 其他 静态函数 cpp      更新时间:2023-10-16

hello.cpp文件中,我有这个静态函数。

static void hello()
{
std::cout << "hello" << std::endl;
}

我想从文件中的其他静态函数调用此函数world.h如下所示。

static void world()
{
hello();
std::cout << "world" << std::endl;
}

在这种情况下,将hello()公开给其他文件的最推荐方法是什么?

这样,关键字static使函数的链接"内部"。 这意味着hello()只能从hello.cpp中可见,即使您将其声明给其他编译单元。

例如,下面的代码产生链接错误(未解析的外部引用(:

您好.cpp:

#include <iostream>
static void hello()
{
std::cout << "hello" << std::endl;
}

你好:

#pragma once
void hello(); // OK, it's declared

主.cpp:

#include "hello.h"
void main()
{
hello(); // But ouch, it's not resolved! The linker can't access to the code you wrote in hello.cpp due to the fact hello() is static!
}

因此,根据定义,您不能以这种方式公开函数。

现在,如果你声明你的函数static并直接在其头文件中实现它,在从hello.cpp中删除hello()的代码后:

你好:

#pragma once
static void hello() 
{
std::cout << "hello" << std::endl;
}

您最终将得到与包含此文件的编译单元一样多的函数hello()。尝试在多个.cpp文件中包含hello.h,并从每个文件中获取指向此 hello 函数的指针。您将看到它们的地址不同:

主.cpp:

#include <iostream>
#include "otherFile.h"
void main()
{
void * pf = hello; // Gives 0x01181810 during the test I'm currently doing while writing
tryWithAnotherCppFile();
}

其他文件.h:

#pragma once
void tryWithAnotherCppFile();

其他文件.cpp:

#include "otherFile.h"
#include "hello.h"
void tryWithAnotherCppFile()
{
void * pf = hello; // Here it gives 0x01181d40, which is different!
}

现在,hello.h以下方式进行更改,将hello()声明为inline而不是static

你好:

#pragma once
inline void hello() 
{
std::cout << "hello" << std::endl;
}

并重做与上面相同的测试:您将看到hello()的地址现在相同,无论包含hello.h的 cpp 文件(0x003c13de,就我这边,现在(。您的函数不再是静态的,它具有外部链接,并且是唯一的,并且在所有编译单元之间共享。

本教程中提供了更多详细信息。 一篇相关的文章,但我建议阅读整篇文章:

当符号具有内部链接时,它仅在 当前翻译单位。不要将此处可见的术语与 访问权限,如私有。此处的可见性意味着链接器将 只能在处理翻译单元时使用此符号 在其中声明符号,而不是以后(与带有 外部链接(。在实践中,这意味着当您声明 符号在头文件中具有内部链接,每次翻译 您包含此文件的单元将获得其自己唯一的副本 象征。

如果它在类的公共范围内,我们可以使用范围解析运算符( :: ( 来访问静态函数,而无需启动对象。

class Hello
{
public:
static void Hello1()
{
printf("Hellon");
}
};

然后从另一个类即世界.cpp(记住包括hello.h文件(。

class World
{
public:
World(){
Hello::Hello1(); 
std::cout << "World" << std::endl;
}
};