Как вы определяете глобальную функцию в С++?

Мне нужна функция, которая не является членом класса и доступна из любого класса.

Я предполагаю, что мне нужно #include заголовочный файл, где объявлена ​​функция, но я не знаю, где определить такую ​​глобальную функцию.

Есть ли веские причины против такой функции в первую очередь?

Ответы

Ответ 1

вам нужно тело (в файле cpp):

int foo()
{
    return 1;
}

и определение/прототип в файле заголовка, который будет включен перед любым использованием функции:

#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
    int foo();
#endif

затем используя его в другом месте:

#include foo.h
void do_some_work()
{
    int bar = foo();
}

или использовать встроенную функцию (не гарантирует, что она будет встроена, но полезна для небольших функций, таких как foo):

#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
    inline int foo()
    {
        return 1;
    }
#endif

альтернативно вы можете злоупотреблять функциями на основе заголовка C-стиля (так что это идет в заголовке, static заставляет его существовать только в одном модуле компиляции, вы должны избегать этого):

#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
    static int foo()
    {
        return 1;
    }
#endif

Ответ 2

То, что вы называете глобальной функцией, обычно называется свободной функцией, и они Хорошая вещь.

Вы определяете его так же, как функцию-член класса, но вне области этого класса.

double squared(double x) {
    return x*x;
}

Простые функции, которые вы можете определить с помощью ключевого слова inline в файле заголовка или просто объявить его там

double squared(double x);

и поместите реализацию (первый пример) в файл *.cpp.

Ответ 3

В файле заголовка:

// someheader.h
#ifndef MY_GLOBAL_FUN
#define MY_GLOBAL_FUN

void my_global_fun();    

#endif

В файле реализации:

#include "someheader.h"

void my_global_fun()
{
    // ...
}

В других файлах, требующих этой функции:

#include "someheader.h"

void f()
{
    my_global_fun();
}

Свободные функции, подобные этому, полезны, и не так много аргументов против их использования. В зависимости от вашего варианта использования, вероятно, целесообразно разместить эти функции в определенном namespace, чтобы избежать столкновения имен с другими библиотеками, которые вы можете использовать.

Ответ 4

Подумайте о main(). Функция вроде просто... есть. Он не входит ни в какой класс, структуру или пространство имен. Вы просто объявляете и даете ему тело. Конечно, в случае функций, которые не являются основными, лучше всего поставить прототип в заголовок и определить его в .cpp файле.

Помните, что у C не было классов, а структуры не могли содержать функции-члены. Тогда не было ничего плохого в свободных функциях, а теперь нет.

Ответ 5

Вы должны объявить свой прототип в файле заголовка и определить его в файле реализации.

//file.h
void foo();

//file.cpp
void foo ()
{}

Чтобы ответить на второй вопрос, нужны глобальные функции, когда они используются несколькими различными классами и типами в общем виде. Например, математические функции.

В противном случае вы можете избежать так многих глобальных функций. Также вам следует избегать наличия локального члена static или глобальных данных, связанных с такой функцией (так что вам не нужно беспокоиться о безопасности потоков).

Ответ 6

В дополнение к ответу @Necrolis использование static устарело в пользу неназванных пространств имен. Однако использование неназванных пространств имен и статики создает отдельные копии для каждой единицы перевода, что увеличивает размер двоичного файла. Использование inline лучше, чем оба в этом смысле.

Эти решения позволяют больше оптимизировать работу с использованием компиляторов, но они менее дружественны к кешу по сравнению с определением в исходном файле и затем связаны.