简体   繁体   中英

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

in hello.cpp file, I have this static function.

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

And I would like to call this function from other static function in world.h file like the following.

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

In this case, what is the most recommended way to expose hello() to other files?

If its in Public scope of class, we can use scope resolution operator( :: ) to access the static functions with out initalizing an object.

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

};

Then from the Other Class ie World.cpp (Remember to include the hello.h File).

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

Used that way, the keyword static makes your function's linkage "internal". This means hello() is only visible from hello.cpp , even if you declare it to other compilation units.

For example, the code below produces a linkage error (unresolved external reference):

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!
}

So you can't expose your function that way, by definition.

Now, if you declare your function static and implement it straight in its header file, after having removed hello() 's code from hello.cpp :

hello.h:

#pragma once

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

You will end up with as many functions hello() as you have compilations units that include this file. Give a try by including hello.h in several .cpp files and take a pointer to this hello function from each of these files. You will see that their addresses differ:

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!
}

Now, change hello.h the following way, by declaring hello() as inline instead of static :

hello.h:

#pragma once

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

And redo the same test as above: you will see that hello() 's address is now the same regardless the cpp file that includes hello.h ( 0x003c13de , on my end, right now). Your function is no longer static, it has an external linkage and is unique and shared among all compilation units.

Further details are available in this tutorial . One relevant piece, but I suggest reading the whole thing:

When a symbol has internal linkage, it will only be visible within the current translation unit. Do not confuse the term visible here with access rights like private. Visibility here means that the linker will only be able to use this symbol when processing the translation unit in which the symbol was declared, and not later (as with symbols with external linkage). In practice, this means that when you declare a symbol to have internal linkage in a header file, each translation unit you include this file in will get its own unique copy of that symbol.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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