Дело в том, что сложные программы на C ++ создаются путем компиляции нескольких объектов, а затем их соединения. Каждый объект обычно является результатом компиляции одного файла реализации (например, «.cpp», «.cc» и т. Д.), Который может прямо или косвенно включать в себя множество заголовков. Следовательно, если вы напишите хороший класс и поместите код в заголовок, то этот код может быть включен в несколько объектных файлов, а затем компилятор генерирует его избыточно, и далее - компоновщик не будет (и не может легко) сравнивать версии, чтобы увидеть, являются ли они эквивалентными, и удалить избыточные копии (проще, если использовать относительные адреса - «позиционно-независимый код» - но это уже другая история). Смотрите также комментарий Джальфа ниже.
Таким образом, вы не хотите, чтобы в ваших заголовках были разные функции вне строки. Если они являются номинально inline
функциями - из-за использования ключевого слова inline или определения внутри класса - тогда компилятору просто придется выполнить дополнительную работу и убедиться, что любая их внеплановая версия представлена уникальным образом. в исполняемом файле. Но для функций вне линии бремя остается за программистом.
Кроме того, если вы предоставляете реализацию в своих заголовках, она избыточно компилируется для каждого объекта, и любое изменение заголовка приведет к перекомпиляции всех зависимых объектов. Внешние функции в отдельных объектах могут быть изменены, этот отдельный объект перекомпилирован, затем он может быть связан с другими уже существующими объектами для формирования нового исполняемого файла. В крупных проектах это экономит МНОГО времени компиляции.