Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Oшибка circular unit reference, Oшибка circular unit reference 
V
    Опции темы
Дмитрий01
Дата 29.8.2015, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 29.8.2015
Где: Сестрорецк Примор ск. ш. д. 285

Репутация: нет
Всего: нет



Oшибка "circular unit reference" вот в таком коде:
Код

unit BaseUnit;
type TBase = class
  owner : TOwner;
  ...
end;

unit OwnerUnit;
type TOwner = class
  a : TA;
  b : TB;
  ...
end;

unit AUnit;
type TA = class(TBase)
  ...
end;

unit BUnit;
type TB = class(TBase)
  ...
end;


Что делать?
PM MAIL   Вверх
Poseidon
Дата 29.8.2015, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Пропиши во всех модулях остальные модули в uses после implementation

Добавлено через 2 минуты и 26 секунд
Хотя нет, у тебя тут все сложнее. Проще все в один модуль запихнуть. А вообще тут изначально ошиюбка в иерархии классов.


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Дмитрий01
Дата 29.8.2015, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 29.8.2015
Где: Сестрорецк Примор ск. ш. д. 285

Репутация: нет
Всего: нет



В один модуль всё запихивать не хочу: слишком длинно будет.
А что посоветуете на счёт иерархии?
PM MAIL   Вверх
Poseidon
Дата 29.8.2015, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



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


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
dnek
Дата 30.8.2015, 14:30 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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
PM MAIL   Вверх
Дмитрий01
Дата 30.8.2015, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 29.8.2015
Где: Сестрорецк Примор ск. ш. д. 285

Репутация: нет
Всего: нет



Цитата(Poseidon @ 29.8.2015,  19:21)
Не правильно использовать в базовом классе параметры, у которых тип - дочерний класс. Другими словами, родитель ничего не должен знать о своих потомках.

Мне этого и не нужно. Мне нужно только, чтобы объект A  мог при необходимости обратиться к B и наоборот.
PM MAIL   Вверх
Poseidon
Дата 30.8.2015, 23:49 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Цитата(Дмитрий01 @  30.8.2015,  21:53 Найти цитируемый пост)
Мне нужно только, чтобы объект A  мог при необходимости обратиться к B и наоборот. 
Вот наоборот быть не должно. Если А обращантся к В, то В считается родительским и он ничего не должен знать про А. Посмотри к примеру иерархию VCL. Там родительские классы не знают ничего про дочерние. Или еще пример: базовый класс в Delphi - TObject. Это красс-родитель для всех остальных классов и он ничего не знает не про одного своего потомка. Поэтому если у тебя появилась необходимость обратится из В к А, то надо что-то менять в логике программы.



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Дмитрий01
Дата 1.9.2015, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 29.8.2015
Где: Сестрорецк Примор ск. ш. д. 285

Репутация: нет
Всего: нет



Я бы хотел, чтобы А и В обращались друг к другу, находясь на одном уровне иерархии. Разве это недопустимо?
PM MAIL   Вверх
Poseidon
Дата 1.9.2015, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Цитата(Дмитрий01 @  1.9.2015,  13:08 Найти цитируемый пост)
Я бы хотел, чтобы А и В обращались друг к другу, находясь на одном уровне иерархии.
Что бы они общались на одном уровне иерархии, надо их обоих сделать потомками одного родителя, и все общие методы описать у родителя. Тогда не понадобится у A создавать параметры типа B, а у B - параметры типа А.



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
dnek
Дата 2.9.2015, 09:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 0
Регистрация: 1.4.2013

Репутация: нет
Всего: нет



Цитата

   Если А обращантся к В, то В считается родительским и он ничего не должен знать про А
   

Это верно только если А наследуется от В а не обращается.
Цитата

   Я бы хотел, чтобы А и В обращались друг к другу, находясь на одном уровне иерархии. Разве это недопустимо?
   

Не только допустимо но еще и является стандартной часто используемой практикой.
В Вашем случае есть 3 выхода из ситуации:
1. Классы обращающиеся друг к другу запихнуть в один юнит (самый простой, быстрый и удобный выход)
2. Использовать приведение к типу как я писал выше (наиболее часто используемый)
3. Ввести поддержку интерфейсов в этих классах и вынести их объявление в отдельный юнит (наиболее профессиональный подход но не всегда оправдывает затраченные время и силы)

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
Poseidon
Дата 2.9.2015, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Цитата(dnek @  2.9.2015,  09:07 Найти цитируемый пост)
В Вашем случае есть 3 выхода из ситуации

dnek, в данном случае на лицо не верно спроектированная иерархия классов. TBase, на сколько я понимаю, задумывался как базовый класс, коим он и является для TA и TB. В то же время TBase содержит в себе параметр типа TOwner. И все бы хорошо, но TOwner содержит парамеры типа TA и TB. Другими словами, из TBase мы вполне себе можем достучаться до TA (TBase.owner.a). Т.е. из родителя имеем доступ к потомку, а это в корне не правильно. Пихание в один юнит избавит от ругательств компилятора, но не избавит от дальнейших ошибок на уровне проектирования. В лучшем случае нарвемся на вечный цикл и, как следствие, мертвое зависание программы.




--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
dnek
Дата 2.9.2015, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 0
Регистрация: 1.4.2013

Репутация: нет
Всего: нет



Да кто Вам сказал что это неправильно. Как пример - TControl.Parent и TComponent.Owner
Другое дело, что TOwner.a и TOwner.b корректнее было бы объявить как TBase и правильно спроектировать его, но TOwner может не знать о TBase но знать TA и TB. Да и TBase лучше объявить как abstract.

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
dnek
Дата 2.9.2015, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 0
Регистрация: 1.4.2013

Репутация: нет
Всего: нет



Нельзя объявлять только что-то типа "TBase.A: TA;". Это действительно недопустимо. Только "TBase.A: TBase;"

А с промежуточным классом, который не наследуется от TBase - сколько угодно и как угодно.

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
Poseidon
Дата 2.9.2015, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Цитата(dnek @  2.9.2015,  14:23 Найти цитируемый пост)
Да кто Вам сказал что это неправильно. Как пример - TControl.Parent и TComponent.Owner
Ну хотя бы Стив Макконнелл в своей книге "Совершенный код" посвещает этому вопросу очень большое внимание. 

Возьмем хотя бы TControl. Базовый класс - TComponent. Возьмите реализацию TComponent, там нет ни намека на его потомка - TControl. Вы никак не выйдете из TComponent к TControl, кроме как прямым преобразованием. В нашем же случае с TBase можно легко выйти на потомка TA, а этого быть не должно.

Цитата(dnek @  2.9.2015,  14:23 Найти цитируемый пост)
TOwner может не знать о TBase но знать TA и TB.
К TOwner вообще нет притензий, тут все норально. Вопросы есть к TBase.





--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
dnek
Дата 2.9.2015, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 0
Регистрация: 1.4.2013

Репутация: нет
Всего: нет



Цитата

   Ну хотя бы Стив Макконнелл в своей книге "Совершенный код" посвещает этому вопросу очень большое внимание
   

Теория и практика разные вещи
Посмотрите на объявление TControl и TWinControl в модуле Controls:
Код

  TControl = class(TComponent)
  private
    FParent: TWinControl;
  ...


  TWinControl = class(TControl)
  ...


После этого, если хотите, продолжим дискуссию :)

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1317 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.