2013-04-11 4 views
1

, относящиеся к предыдущему question, у меня сейчас следующий:Избегайте круговой зависимости?

В следующем декорациях:

class B; 

class A 
{ 
    // stuff, methods and so on 
    B b; 
}; 

class B 
{ 
    // stuff, methods and so on 
    A a; 
}; 

Здесь мы имеем круговую зависимость между A и B, но этот код плохо формируется с B является неполным типом. Решение состоит в том, чтобы изменить B указателем B с помощью умных указателей, например. Но добавление указателя увеличивает сложность и ресурсы, затрачиваемые ненужно, поскольку вам не нужен указатель!

В предыдущем question Я старался избегать использования указателей с помощью шаблонов, поэтому я задерживаю создание класса в точке, где определены оба класса, но я был неспособен сделать это успешно.

Невозможно ли избежать указателей? Существуют ли хорошо известные дескрипторы, чтобы избежать круговых зависимостей?

+6

Это не имело бы смысла, если бы оно скомпилировалось. Вы говорите, что экземпляр 'A' содержит экземпляр' B', но экземпляр 'B' содержит экземпляр' A' тоже. Для создания такого объекта вам понадобится бесконечное количество памяти и бесконечное количество времени. То есть конструктор 'A' и конструктор' B' будут бесконечно возвращаться. – cdhowie

+1

Почему вы пытаетесь избежать указателей? – metalhead

+3

Вы также можете использовать ссылки. – dyp

ответ

8

Невозможно избежать какой-либо формы ссылки, например указатели.

Как вы пытаетесь это сделать, в определении есть бесконечная рекурсия. Номер A включает в себя B, который включает в себя и A, и так далее. Таким образом, оба класса потребуют бесконечного хранения, что, очевидно, бессмысленно.

Если у вас действительно есть модель, в которой A содержит B и B содержит A то эти классы кажутся неспособными жить друг без друга. В этом случае, возможно, у вас действительно есть только один класс, а не два.

+0

Я предполагаю, что в этом случае это возможно, так как есть только один из них без каких-либо других полей. Поэтому он не размножается. Но да, в любом другом случае потребуется бесконечная память. – Mysticial

+0

@DyP Это примерно так же полезно, как можно получить, когда вопрос не указывает * почему * OP хочет сделать это. – cdhowie

+4

@ DyP Проводка о том, что запрос OP невозможна, является допустимым способом ответа на SO. – Mysticial

7

Компилятор должен определить место, необходимое для B.

Как это сделать? Выясняется, что требуемое пространство имеет размер A.

Но размер A является размером B. Вернемся к квадрату, и компилятору придется зацикливаться навсегда, чтобы понять это. Следовательно, он не компилируется.

Единственное решение - это разбить этот цикл. Используйте указатель (умный или другой).

3

Я не думаю, что это в первую очередь проблема компилятора (но это не может сделать этого), а скорее проблема в вашем дизайне: член данных выражает право собственности. Если A имеет член данных типа B, то экземпляр A имеет экземпляр B.

Если же справедливо и для B, то вы будете либо получить круговую собственность (a владеет b и b владеет a) или бесконечный ряд a0 владеет b0 владеет a1 владеет b1 .....

Поэтому , вам нужно будет указать хотя бы один из двух типов, в которых экземпляры не имеют экземпляры другого типа. Вы можете сделать это на C++ с помощью (умных) указателей или ссылок или передать объект каждой функции-члену класса, где это необходимо.

+0

+1, Лучший ответ ..... –

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