Ошибка, которую вы получаете, останавливает ваш код от компиляции до того, как дружба станет проблемой.
Вы объявили бюджет как неполный тип:
class Budget;
А затем написал код, который вызывает функции перед тем, как класс будет определен. Это не разрешено. Вы должны объявить функции, которые его используют, но НЕ определять его до тех пор, пока класс не будет определен.
Вот почему (одна из причин) мы помещаем объявления классов в заголовки, а реализации в файлы .cpp. Это также уменьшает связь между файлами и может помочь в увеличении скорости сборки.
Вот сжатая версия вашего кода, которая компилируется, с удалением большинства необязательных строк (как вы должны попытаться сделать в будущих вопросах):
class Budget;
class AuxiliaryOffice {
double auxBudget = 0;
public:
void addBudget(double a, Budget &ref);
};
class Budget {
// Unrelated, but useful to know:
// inline statics can be initialized in the class like this, no
// definition necessary in the .cpp file.
inline static double corpBudget = 0;
friend void AuxiliaryOffice::addBudget(double, Budget&);
};
// if in .cpp, remove "inline", if in header, keep it
inline void AuxiliaryOffice::addBudget(double a, Budget &ref) {
ref.corpBudget += a;
}
посмотреть вживую: https://godbolt.org/z/JYDZMz