В C++ функцию-член класса можно объявить:
Внутри класса (inline определение):
class A { void foo() { /* ... */ } // непосредственно внутри класса };
Такие функции считаются неявно inline.
Внутри класса (только объявление):
class A { void foo(); // только объявление }; void A::foo() { /* ... */ } // определение вне класса
Отличие:
inline, компилятор может внедрить такую функцию прямо в код её вызова.inline без явного указания (inline), хотя ключевое слово можно добавить:
inline void A::foo() { /* ... */ }
Преимущества и недостатки подходов:
Всегда ли функция, определённая внутри класса, будет реально встроена компилятором?
Ответ: Нет. Ключевое слово inline (включая неявное присваивание при определении внутри класса) — это лишь пожелание компилятору. Компилятор может проигнорировать этот совет, если посчитает функцию слишком сложной или нецелесообразной для встраивания.
История 1
В большом проекте функции-члены были определены как
inlineвнутри заголовочных файлов и включались в тысячи translation units, в результате чего время компиляции выросло в несколько раз, а бинарник увеличился из-за дублирования кода — компилятор не всегда объединяет идентичную машинную реализацию.
История 2
В попытке ускорить выполнение, разработчик вынес всю логику класса в объявление (в .h-файл). Это привело к тому, что при изменении функции пересобирался весь проект, а не только отдельные файлы (к которым была реально затронута интеграция).
История 3
Новый участник команды поместил длинные методы сериализации и работы с файлами прямо в объявление шаблонного класса, вызвав случайное распространение ошибок по всем TU, и излишний рост размера исполняемого файла без прироста производительности.