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

时间:2018-07-04 08:37:46

标签: c++ function static

hello.cpp文件中,我具有此静态功能。

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

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

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

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

2 个答案:

答案 0 :(得分:1)

如果它在类的Public范围内,我们可以使用范围解析运算符(::)在不初始化对象的情况下访问静态函数。

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

};

然后从其他类(即World.cpp)(请记住包括hello.h文件)。

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

答案 1 :(得分:1)

以这种方式使用的关键字static使函数的链接“内部”。 这意味着hello()仅在hello.cpp中可见,即使您将其声明给其他编译单元也是如此。

例如,以下代码产生链接错误(未解析的外部参考):

hello.cpp:

#include <iostream>

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

hello.h:

#pragma once

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

main.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()的代码后,声明了函数hello.cpp并直接在其头文件中实现了该功能:

hello.h:

#pragma once

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

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

main.cpp:

#include <iostream>
#include "otherFile.h"

void main()
{
    void * pf = hello; // Gives 0x01181810 during the test I'm currently doing while writing

    tryWithAnotherCppFile();
}

otherFile.h:

#pragma once

void tryWithAnotherCppFile();

otherFile.cpp:

#include "otherFile.h"
#include "hello.h"

void tryWithAnotherCppFile()
{
    void * pf = hello; // Here it gives 0x01181d40, which is different!
}

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

hello.h:

#pragma once

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

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

this tutorial中提供了更多详细信息。 一篇相关的文章,但我建议阅读全文:

  

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