От веб-сайтов, с помощью Firefox, я использую расширение CopyPlainText.
Чтобы определить класс или структуру, компилятор должен знать, насколько велика каждая переменная-член этого класса. Форвардное объявление этого не делает. Я когда-либо видел, как он используется для указателей и (реже) ссылок.
Кроме того, то, что вы пытаетесь сделать здесь, невозможно. У вас не может быть класса A, который содержит объект другого класса B, который содержит объект класса A. Вы можете , однако, чтобы класс A содержал объект указатель на класс B, который содержит объект класса A.
B.cpp
#include "B.h"
void B::SomeFunction()
{
}
Bh
#ifndef __B_h__ // idempotence - keep header from being included multiple times
#define __B_h__
#include "A.h"
class B
{
public:
A a;
void SomeFunction();
};
#endif // __B_h__
Ah
#ifndef __A_h__ // idempotence - keep header from being included multiple times
#define __A_h__
#include "B.h"
class B; // forward declaration
struct A
{
B *b; // use a pointer here, not an object
};
#endif // __A_h__
Две точки. Во-первых, обязательно используйте какую-либо форму идемпотентности, чтобы заголовки не включались несколько раз в единицу компиляции. Во-вторых, поймите, что в C ++ Единственное различие между классами и структурами - это уровень видимости по умолчанию: классы используют частную видимость по умолчанию, а структуры используют публичную видимость по умолчанию. Следующие определения функционально эквивалентны в C ++.
class MyClass
{
public: // classes use private visibility by default
int i;
MyClass() : i(13) { }
};
struct MyStruct
{
int i;
MyStruct() : i(13) { }
};
Здесь меня бросают в глаза две проблемы:
1: Вы написали Struct A
вместо struct A
; обратите внимание на строчную букву «s». Ваш компилятор может рассмотреть эквивалент, но я не думаю, что это стандартный C ++.
Вы определили круговую ссылку между A
и B
. Каждый объект A должен содержать объект B
, но каждый объект B
должен содержать объект A
! Это противоречие, и оно никогда не будет работать так, как вы хотите. Обычный способ C ++ решить эту проблему - использовать указатели или ссылки для A :: b
или B :: a
(или обоих).
public:
A a;
Вы пытаетесь создать объект A только с предварительным объявлением. Компилятор в этот момент (только с прямым объявлением) не может определить размер объекта A и, следовательно, он не может выделить память, необходимую для A. Таким образом, вы не можете создавать объекты только с прямым объявлением.
Вместо этого замените на:
A* a;
Указатель или ссылка на A без определения класса будет работать нормально.
Прямые объявления, такие как
struct A;
или
class A;
Представьте A как неполный тип , и он останется неполным до тех пор, пока не будет достигнут конец определения типа. Есть вещи, которые можно сделать с неполными типами, и то, что нельзя. Вы можете
Вы не можете
В вашем коде вы пытаетесь объявить член структуры неполного типа. Это незаконно. Разрешены только указатели и ссылки.
Если вы создадите экземпляр A, это создаст экземпляр B (член var), который создаст экземпляр A (член var), который создаст экземпляр B, который создаст экземпляр A и так далее ... Компилятор не должен допускать этого, поскольку для этого требуется бесконечная память.
Чтобы решить эту проблему, либо A, либо B должны использовать ссылку / указатель на другой класс.
Вы также включаете Ah из Bh и Bh из Ah Вы должны хотя бы использовать макросы препроцессора:
#ifndef __A_H__
#define __A_H__
// A.h contents
#endif
, чтобы файл не был включен более одного раза.