Как выставить статическую функцию в файле cpp другим файлам - PullRequest
0 голосов
/ 04 июля 2018

в hello.cpp файле, у меня есть эта статическая функция.

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

И я хотел бы вызвать эту функцию из другой статической функции в файле world.h, как показано ниже.

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

В этом случае, каков наиболее рекомендуемый способ предоставления hello() другим файлам?

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

При таком использовании ключевое слово 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 файлов, и возьмите указатель на эту функцию приветствия из каждого из этих файлов. Вы увидите, что их адреса различаются:

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() теперь тот же, независимо от файла cpp, который включает hello.h (0x003c13de, с моей стороны, прямо сейчас). Ваша функция больше не статична, имеет внешнюю связь, уникальна и используется всеми модулями компиляции.

Более подробная информация доступна в этом руководстве . Одна важная статья, но я предлагаю прочитать ее целиком:

Когда символ имеет внутреннюю связь, он будет виден только внутри текущий переводческий блок. Не путайте термин, видимый здесь, с права доступа вроде приватные. Видимость здесь означает, что компоновщик будет использовать этот символ только при обработке единицы перевода в котором символ был объявлен, а не позже (как с символами с внешняя связь). На практике это означает, что когда вы объявляете символ для внутренней ссылки в заголовочном файле, каждый перевод блок, в который вы включаете этот файл, получит свою уникальную копию символ.

0 голосов
/ 04 июля 2018

Если это в 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;
    }
};
...