بخاطر این که b ای که داخل کلاس تعریف کردید از نوع "اشاره گر" نیست
شما forward declration کلاس را با تابع اشتباه گرفتید . چون تابع از نوع اشاره گر هست برای توابع forward declration کار می کنه .
اگر متغیر از نوع اشاره گر نباشه حتما باید زمان کامپایل نوع متغیر مشخص باشه. (چون کامپایلر باید زمان کامپایل کد بدونه اندازه متغیر چه مقداری هست تا بتونه متغیر رو با سایز مشخص بسازه. اگرforward delcration کلاس بعد از استفاده هم قرار باشه درست باشه کامپایلر مجبور میشه تمام translation unitهای برنامه رو چک کنه و ببینه که آیا اون کلاس وجود داره یا نه که عملا باعث میشه شما نتونید داخل 2 تا فایل .cpp جدا از هم 2 تا کلاس با اسم یکسان تعریف کنید... . چون اشاره گر ها سایز ثابتی دارند(4یا 8 بایت) کامپایلر نیازی به چک کردن چیزی نداره )
کدی که شما نوشتید معادل کد زیر هست که کار نمی کنه :
class B;
int main(){
B b;
}
class B{};
به این شکل تعریف کنید :
class B;
class A{
public:
B* b;
};
class B{};
int main()
{
A a;
}