Избегать круговой зависимости?

Связанный с предыдущим вопрос, У меня сейчас следующее:

В следующем пейзаже:

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 с помощью умных указателей, например. Но добавление указателя увеличивает сложность и увеличивает затраты ресурсов, так как указатель вам не нужен!

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

Возможно ли избежать указателей? Существуют ли известные схемы, чтобы избежать циклических зависимостей?

1

Решение

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

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

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

8

Другие решения

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

Как оно работает? Получается, что требуемое пространство имеет размер A,

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

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

7

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

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

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

3
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector