Как вы определяете глобальную функцию в C ++? - PullRequest
21 голосов
/ 29 июля 2011

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

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

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

Ответы [ 6 ]

26 голосов
/ 29 июля 2011

вам нужно тело (в файле 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
6 голосов
/ 29 июля 2011

То, что вы называете глобальная функция обычно называется свободной функцией , и они A Good Thing .

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

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

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

double squared(double x);

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

3 голосов
/ 29 июля 2011

В заголовочном файле:

// 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, чтобы избежать конфликта имен с другими библиотеками, которые вы можете использовать.

0 голосов
/ 24 декабря 2015

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

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

0 голосов
/ 29 июля 2011

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

//file.h
void foo();

//file.cpp
void foo ()
{}

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

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

0 голосов
/ 29 июля 2011

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

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

...