experiment.h
необязательно включать simulation.h
или форвард объявить _simulation
, поскольку определение _experiment
не зависит от _simulation
вообще.
У вас уже есть предварительное объявление или _experiment
в simulation.h
, что хорошо, поскольку определение _simulation
содержит указатель на _experiment
, поэтому полное определение не требуется.
Чего не хватает, так это определения обоих классов в исходных файлах. Включите оба заголовка из обоих исходных файлов, поскольку им нужны определения классов, и все должно быть хорошо.
В общем, если вы включите все заголовки, которые вам нужны, в исходные файлы и включите заголовок из другого заголовка только тогда, когда вам нужно больше, чем предварительное объявление, то вы в основном избежите проблем с циклической зависимостью.
Вам также необходимо добавить защитные заголовки для заголовков, чтобы избежать нескольких определений в тех случаях, когда вам нужно включать заголовки из других заголовков.
Какой тогда смысл объявления форварда?
Это позволяет вам объявить, что класс существует, без необходимости объявлять что-либо еще, от чего зависит класс. Вы можете сделать несколько полезных вещей, таких как определить указатели или ссылки на класс, или объявить функции с классом в качестве аргумента или возвращаемого типа, используя только предварительное объявление. Вы просто не можете делать ничего, что требует знания размера или членов класса.