![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
Дмитрий01 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 29.8.2015 Где: Сестрорецк Примор ск. ш. д. 285 Репутация: нет Всего: нет |
Oшибка "circular unit reference" вот в таком коде:
Что делать? |
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Пропиши во всех модулях остальные модули в uses после implementation
Добавлено через 2 минуты и 26 секунд Хотя нет, у тебя тут все сложнее. Проще все в один модуль запихнуть. А вообще тут изначально ошиюбка в иерархии классов. -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
Дмитрий01 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 29.8.2015 Где: Сестрорецк Примор ск. ш. д. 285 Репутация: нет Всего: нет |
В один модуль всё запихивать не хочу: слишком длинно будет.
А что посоветуете на счёт иерархии? |
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Не правильно использовать в базовом классе параметры, у которых тип - дочерний класс. Другими словами, родитель ничего не должен знать о своих потомках.
-------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
dnek |
|
|||
Новичок Профиль Группа: Участник Сообщений: 0 Регистрация: 1.4.2013 Репутация: нет Всего: нет |
Согласен с Poseidon.
Я бы даже сказал что это недопустимо и ломает основополагающие принципы наследования. Но в данном случае проблема не в этом. Если Вы хотите использовать именно такую структуру unit-ов, то: 1. В BaseUnit TBase.owner объявить как TObject, в uses секции implementation добавить OwnerUnit а в коде использовать приведение к типу - TOwner(owner) 2. В OwnerUnit TOwner.a и TOwner.b объявить как TBase, в uses секции interface добавить BaseUnit а в коде использовать приведение к типу - TA(a) и TB(b) но лучше корректно спроектировать TBase и избежать этого Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
Дмитрий01 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 29.8.2015 Где: Сестрорецк Примор ск. ш. д. 285 Репутация: нет Всего: нет |
Мне этого и не нужно. Мне нужно только, чтобы объект A мог при необходимости обратиться к B и наоборот. |
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
-------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
Дмитрий01 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 29.8.2015 Где: Сестрорецк Примор ск. ш. д. 285 Репутация: нет Всего: нет |
Я бы хотел, чтобы А и В обращались друг к другу, находясь на одном уровне иерархии. Разве это недопустимо?
|
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
-------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
dnek |
|
||||
Новичок Профиль Группа: Участник Сообщений: 0 Регистрация: 1.4.2013 Репутация: нет Всего: нет |
Это верно только если А наследуется от В а не обращается.
Не только допустимо но еще и является стандартной часто используемой практикой. В Вашем случае есть 3 выхода из ситуации: 1. Классы обращающиеся друг к другу запихнуть в один юнит (самый простой, быстрый и удобный выход) 2. Использовать приведение к типу как я писал выше (наиболее часто используемый) 3. Ввести поддержку интерфейсов в этих классах и вынести их объявление в отдельный юнит (наиболее профессиональный подход но не всегда оправдывает затраченные время и силы) Этот ответ добавлен с нового Винграда - http://vingrad.com |
||||
|
|||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
dnek, в данном случае на лицо не верно спроектированная иерархия классов. TBase, на сколько я понимаю, задумывался как базовый класс, коим он и является для TA и TB. В то же время TBase содержит в себе параметр типа TOwner. И все бы хорошо, но TOwner содержит парамеры типа TA и TB. Другими словами, из TBase мы вполне себе можем достучаться до TA (TBase.owner.a). Т.е. из родителя имеем доступ к потомку, а это в корне не правильно. Пихание в один юнит избавит от ругательств компилятора, но не избавит от дальнейших ошибок на уровне проектирования. В лучшем случае нарвемся на вечный цикл и, как следствие, мертвое зависание программы. -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
dnek |
|
|||
Новичок Профиль Группа: Участник Сообщений: 0 Регистрация: 1.4.2013 Репутация: нет Всего: нет |
Да кто Вам сказал что это неправильно. Как пример - TControl.Parent и TComponent.Owner
Другое дело, что TOwner.a и TOwner.b корректнее было бы объявить как TBase и правильно спроектировать его, но TOwner может не знать о TBase но знать TA и TB. Да и TBase лучше объявить как abstract. Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
dnek |
|
|||
Новичок Профиль Группа: Участник Сообщений: 0 Регистрация: 1.4.2013 Репутация: нет Всего: нет |
Нельзя объявлять только что-то типа "TBase.A: TA;". Это действительно недопустимо. Только "TBase.A: TBase;"
А с промежуточным классом, который не наследуется от TBase - сколько угодно и как угодно. Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Возьмем хотя бы TControl. Базовый класс - TComponent. Возьмите реализацию TComponent, там нет ни намека на его потомка - TControl. Вы никак не выйдете из TComponent к TControl, кроме как прямым преобразованием. В нашем же случае с TBase можно легко выйти на потомка TA, а этого быть не должно. К TOwner вообще нет притензий, тут все норально. Вопросы есть к TBase. -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
dnek |
|
||||
Новичок Профиль Группа: Участник Сообщений: 0 Регистрация: 1.4.2013 Репутация: нет Всего: нет |
Теория и практика разные вещи Посмотрите на объявление TControl и TWinControl в модуле Controls:
После этого, если хотите, продолжим дискуссию :) Этот ответ добавлен с нового Винграда - http://vingrad.com |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |