Я что-то здесь упускаю?
class Foo;
class Bar {
public:
Foo foo;
};
class Foo { };
Ошибка:
ошибка C2079: ‘Bar :: foo’ использует неопределенный класс ‘Foo’
Когда вы объявляете класс вперёд, вы можете создавать указатели и ссылки на него, но вы не можете делать членов типа объявленного заранее класса: полное определение Foo
необходим для определения макета внешнего класса (т.е. Bar
), иначе компилятор не может принять решение о размере и структуре Bar
,
Это разрешено, хотя:
class Foo;
class Bar {
public:
Foo* fooPtr;
Foo& fooRef;
};
Причина, по которой указатели и ссылки на заранее объявленные классы разрешены, заключается в том, что размеры указателей и ссылок не зависят от структуры класса, на который они указывают (или на который они ссылаются).
Да, вы упускаете что-то важное: вопрос.
Я предполагаю, что вы хотите знать, что не так в коде и почему компилятор выдает ошибку.
Компилятор должен знать размер Foo, чтобы вычислить макет класса Bar. Размер объектов Foo определяется их макетом, чтобы знать, что компоновщик компилятору должен знать определение класса. В тот момент, когда вы объявляете переменную-член foo, он просто знает, что Foo существует, но не его размер, потому что вы дали ему только объявление, а не определение раньше.