В C++ есть что-то, называемое Правилом одного определения. Это означает, что (исключая встроенные функции) определения могут появляться только в одном блоке компиляции. Поскольку файлы заголовков C++ просто «копируются и вставляются» в каждый включенный файл, теперь вы помещаете определения в несколько мест, если вы просто поместите определения в файлы заголовков.
Конечно, вы можете сказать, почему бы не сделать все встроенным. Ну, если компилятор уважает ваше встроенное предложение, код для длинных функций будет реплицироваться на каждом сайте вызова, делая ваш код чрезмерно большим и, возможно, вызывая проблемы с кешем, и всевозможные ненужные вещи.
С другой стороны, если компилятор не прослушивает вас и ничего не делает, теперь у вас есть 2 проблемы: 1) вы не знаете, какая единица перевода получила определения ваших классов, и 2) компилятор все равно должен пробираться через ваши определения каждый раз, когда вы # включаете их. Более того, нет простого способа убедиться, что вы случайно не определили тот же метод дважды, в двух разных заголовках, иначе.
Вы также получаете проблему с круговой зависимостью. Чтобы класс вызывал метод другого класса, этот класс должен быть объявлен первым. Поэтому, если 2 классам необходимо вызвать методы друг друга, каждый из них должен быть объявлен до того, как он будет определен. Невозможно сделать это с помощью деклараций и определений в одном файле.
Действительно, именно так были созданы язык и парсер. Это боль, но вам просто нужно иметь дело с этим.
Я имел в виду положить все определение класса в .h и включить его, защищая его с защитой заголовка –
Что произойдет, если вы включите этот файл .h в более чем одном месте в одном исполняемом файле? Ans: вы получаете множество определений одних и тех же функций. - Реальный момент здесь заключается в том, что вы можете делать всевозможные дурацкие вещи с помощью правил, но они почти всегда оказываются неработоспособными на практике как обычные способы. –