2013-05-10 4 views
-8

Вот код:Как обрабатывать классы, которые ссылаются друг на друга?

class B 
{ 
    A a; 
}; 

class A 
{ 
    B b; 
}; 

int main() 
{ 
    return 0; 
} 

Вот ошибка:

1>c:\mine\visual studio 2010 projects\myproj\compiled equivalent.cpp(7): 
    error C2079: 'B::a' uses undefined class 'A' 
+1

это действительно очень простой, и я не пытаюсь быть злым, но вы должны понять это с небольшим количеством поисков. –

+1

Да ... Как это сработает? 'A myA; myA.b.a.b.a.b.a.b.a.ba.a.b ... ' – mwerschy

+1

http://en.wikipedia.org/wiki/Forward_declaration –

ответ

8

Вы не можете. Два класса не могут содержать друг друга в качестве членов. Подумайте над ответом на вопрос «Что такое размер типа A?» Ну A содержит B, так какой размер B? Ну B содержит A, так какой размер A? О, дорогой, у нас бесконечный цикл. Как мы можем сохранить этот объект в конечной памяти?

Возможно, более подходящей структурой было бы включение одного из классов в указатель на другой тип. Тип, который указывается просто может быть вперед объявлены до того, как член указатель объявлен:

class A; // A is only declared here, so it is an incomplete type 

class B 
{ 
    A* a; // Here it is okay for A to be an incomplete type 
}; 

class A 
{ 
    B b; 
}; 

Теперь тип B не содержит A, он просто содержит указатель к A. Для этого не обязательно должен быть объект A, поэтому мы нарушили бесконечный цикл.

0

Учитывая, что вы запрашиваете ссылки между классами, возможно, вы пришли из Java, C# или аналогичного фона, где можно только помещать ссылки на объекты внутри других объектов.

В C++ таких ограничений нет: вам разрешено иметь содержимое одного объекта полностью вложенным внутри другого. Но для этого вы должны заранее указать определение вложенного объекта. C++ нуждается в этом определении, чтобы вычислить размер и расположение внешнего объекта. Чтобы избежать этого гнезда, вам нужно разместить не сам объект, а pointer или reference его внутри внешнего объекта.

Это, как говорится,

// C# 
class A 
{ 
    int x; 
    B b; 
} 
class B 
{ 
    int y; 
    A a; 
} 

становится

// C++ 
class B; // tell the compiler that B is a class name 
class A 
{ 
    int x; 
    B *pb; // the forward declaration above allows you to declare pointer to B here 
}; 
class B 
{ 
    int y; 
    A *pa; 
}; 

, если вы решите использовать синтаксис указателей.

То, что это позволяет это иметь такие вещи, как:

// C++ again 
class C 
{ 
    A a; 
    B b; 
    A *pa2; 
}; 

, который имеет расположение в памяти в виде:

C: топорa.pb поb.pa PA2

что не возможно в Java/C#.

Смежные вопросы