Вы должны понимать, что циклическая зависимость означает, что вы можете использовать только соответствующие круговые зависимые классы вместе: если у вас есть циклическая зависимость между, скажем, A
и B
, вы не можете использовать A
или B
самостоятельно в любой программе. Чтобы придерживаться вашей проблемы: конечно, вам не нужны два других друга! Все, что вам нужно, это какой-то способ ссылаться на некоторых и взаимодействовать с ними таким образом, который может быть ограничен их фактическими способностями.
Однако часто бывает, что объекты классов используют друг друга без причины круговой зависимости. С этой целью важно определить, что на самом деле вызывает зависимость между двумя классами/компонентами (они не совсем эквивалентны, но предоставление подробного определения будет несколько длинным). A
зависит от B
при следующих условиях:
- Когда
A
содержит элемент типа B
.
- Когда
A
происходит от типа B
.
- Когда
A
использует значение типа B
как часть сигнатуры функции.
- Когда
A
использует B
в своей реализации.
- Я, наверное, кое-что забыл (я помню, было больше причин, по которым были бы связаны классы).
Если у вас есть циклическая зависимость между двумя классами, могут быть способы разбить эту зависимость. Часто зависимость может быть разбита путем разбиения одного из двух классов на базовый класс и производного класса с базовым классом, не зависящим от другого класса. Существует ряд других подходов к разрыву циклов зависимостей. «Большой масштаб C++» Джона Лакоса (1996), по сути, касается циклов взаимозависимости и мотивации, почему циклические зависимости плохие (я думаю, он не согласился бы с этой упрощающей характеристикой).
...и, да, циклические зависимости являются плохо:
- Они вызывают программы включают в себя ненужную функциональность, потому что вещи валяются, в которых не требуется.
- Они затрудняют тестирование программного обеспечения.
- Они делают намного сложнее рассуждать о программном обеспечении.
- Они значительно упрощают замену частей системы.
- ... и, возможно, ряд других причин.
Вышеупомянутое сформулировано с точки зрения C++. Некоторые из причин круговых зависимостей могут отсутствовать [непосредственно] в C, но те же самые понятия применимы и к C.
В моем опыте основная проблема с циркулярными ссылками - это управление памятью - кому принадлежит что? –
Это ни хорошо, ни плохо: это то, что есть. Если вы чувствуете, что вы должны, остерегайтесь утечек памяти. – YvesLeBorg
В прошлый раз, когда я проверил (иначе мне пришлось скомпилировать это), проект 'llvm' был включен для круговых зависимостей, и они пишут виртуальную машину/компилятор. Вы можете принять это в качестве примера и, возможно, спросить, почему они идут с этим дизайном. – user2485710