Запись функционального определения в заголовочных файлах в C++

61
задан Delgan 22 May 2017 в 07:43
поделиться

6 ответов

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

headera.h:

inline string method() {
    return something;
}

Функции членства неявны встроенный, если они определяются в их классе. Тот же материал верен для них верный: Если они могут быть помещены в заголовок без стычки, можно действительно сделать так.

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

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

Да, который корректен. Функция будет определена в каждом месте, где Вы включаете его заголовок. Компилятор будет заботиться о помещении только одного экземпляра его в получающуюся программу путем устранения других.

67
ответ дан Johannes Schaub - litb 24 November 2019 в 17:21
поделиться

В зависимости от Вашего компилятора и это - настройки, это может сделать любое следующее:

  • Это может проигнорировать встроенное ключевое слово (это - просто подсказка к компилятору, не команда), и генерируйте автономные функции. Это может сделать это, если Ваши функции превышают зависимый от компилятора порог сложности. например, слишком много вложенных циклов.
  • Это может решить, чем Ваша автономная функция является хорошим кандидатом на встроенное расширение.

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

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

  1. компилятор, создающий программу с помощью DLL, мог бы решить не встроить функцию, таким образом, это генерирует ссылку символа на функцию, которая не существует, и DLL не загрузится.
  2. , Если Вы обновляете DLL и изменяете встроенную функцию, клиентская программа будет все еще использовать старую версию той функции, так как функция была встроена в клиентский код.
12
ответ дан Ferruccio 24 November 2019 в 17:21
поделиться

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

то, Что Вы говорите о компиляторе, также верно. Нет никакого различия для compiler— кроме inlining— между кодом в заголовочном файле или .cpp файл.

4
ответ дан Keith Pinson 24 November 2019 в 17:21
поделиться
  1. , Если Ваши функции настолько просты, заставьте их встроить, и необходимо будет засунуть их в заголовочный файл так или иначе. Кроме этого, любые соглашения - просто это - соглашения.

  2. Да, компилятор действительно разворачивает заголовочный файл, где это встречается с #include операторами.

2
ответ дан sykora 24 November 2019 в 17:21
поделиться

Это зависит от стандартов кодирования, которые применяются в Вашем случае, но:

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

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

, Прежде чем объектный файл создается компилятором, которым называют препроцессор (-E опция для gcc), и результат отправляется в компилятор, который создает объект из кода.

, Таким образом, более короткий ответ:

- Объявление функций в заголовке хорошо для скорости (но не для пространства) -

2
ответ дан INS 24 November 2019 в 17:21
поделиться

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

-1
ответ дан Naveen 24 November 2019 в 17:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: