Должен ли я определять статические встроенные методы в файле заголовка? - программирование
Подтвердить что ты не робот

Должен ли я определять статические встроенные методы в файле заголовка?

Я читал о том, как обычно лучше не указывать ничего в заголовочных файлах, потому что избыточные копии создаются для каждого другого файла, который включает файл заголовка. Однако в случае статических встроенных методов кажется, что я должен определить его на месте (по крайней мере, visual studio 2010 не позволяет мне это делать). Поэтому, если я пишу интерфейс в файле заголовка, я не могу определить статический встроенный метод вне определения класса или в файле .cpp.

Итак, должен ли я вообще использовать статические встроенные методы? И связанный вопрос: Должен ли я определять какой-либо метод или переменную в файле заголовка (что относительно констант)?

В любом случае, странно, это не то, что подробно описано в моих книгах на С++.

Изменить: я прочитал похожие вопросы о статических встроенных методах, но ни один из них, по-видимому, напрямую не затрагивает эту проблему.

4b9b3361

Ответ 1

Как добавить определение функции в файл заголовка?

Это может быть достигнуто тремя возможными способами:

  • Отметить функцию inline или
  • Выполнение функции static или
  • Помещение функций в анонимное пространство имен.

Каков правильный способ сделать это?

#1 i.e: Знак функции inline является правильным способом без нарушения правила Одно определение.

Что не так с двумя другими оценками?

В обоих #2 и #3 каждый модуль перевода будет содержать собственную версию функции, а программа будет содержать несколько разных версий функции, что приведет к увеличению размера сгенерированного двоичного файла.
i.e: Для функции static fun(), &fun будет различной в каждой единицы перевода, а программа будет содержать N разные версии функции.
Кроме того, если функция содержит статические локальные переменные, тогда будет N разные статические локальные переменные, по одному для каждого экземпляра функции.

Как первый подход позволяет избежать этой проблемы?

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

Какова сделка с определениями функций static inline в заголовке?

Ключевое слово static заставляет функцию иметь внутреннюю связь.
Каждый экземпляр функции, определенный как встроенный, рассматривается как отдельная функция, и каждый экземпляр имеет свою собственную копию статических локалей и строковых литералов. Таким образом, это будет похоже на #2.

Примечание:
Стандарт требует, чтобы все определения функции inline выполнялись в пользовательской программе. У вас должно быть точно такое же определение во всех единицах перевода, в которых используется или вызывается функция.


Соответствующие ссылки Standerdese:

Стандарт С++ 03

3.2 Одно правило определения:
Параграф 3:

Каждая программа должна содержать ровно одно определение каждой не-встроенной функции или объекта, которая используется в этой программе; не требуется диагностика. Определение может явно отображаться в программе, оно может быть найдено в стандартной или определяемой пользователем библиотеке или (если необходимо), оно неявно определено (см. 12.1, 12.4 и 12.8). Встроенная функция должна быть определена в каждой единицы перевода, в которой она используется.

7.1.2 Спецификаторы функций
Параграф 4:

Встроенная функция должна быть определена в каждой единицы перевода, в которой она используется, и должна иметь точно такое же определение в каждом случае (3.2). [Примечание: вызов встроенной функции может быть встречен до того, как ее определение появится в блоке перевода. ] Если функция с внешней связью объявлена ​​встроенной в одну единицу перевода, она должна быть объявлена ​​встроенной во все единицы перевода, в которых она отображается; диагностика не требуется. Встроенная функция с внешней связью должна иметь один и тот же адрес во всех единицах перевода. Статическая локальная переменная в anextern встроенной функции всегда относится к одному и тому же объекту. Строковый литерал во внешней встроенной функции - это тот же объект в разных единицах перевода.

Ответ 2

(1) Я не могу определить статический встроенный метод вне класса или в файле .cpp.

Вы можете определить метод static inline вне класса в файле заголовка. Демо. Вы не можете определить их в файле .cpp.

(2), я должен вообще использовать статические встроенные методы

Я бы сказал, их можно легко избежать. Если вам нужно увидеть тело в файле заголовка для вашей собственной цели, тогда сделайте только inline.

(3) Должен ли я определить какой-либо метод или переменную в файле заголовка (что касается констант)

  • Внутри тела класса вы можете определить static const данные интегрального тип.
  • static методы могут быть определены внутри тела класса
  • static inline методы могут быть определены внутри тела класса или снаружи тело класса в файле заголовка
  • static члены данных должны быть определены в одном файле .cpp, чтобы придерживаться правила определения 1