|
|
|
|
Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как «свернуть» программу в трей.
3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
… (продолжение следует) …
Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.
Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка — 60 дней. Последующие попытки бан.
Мат в разделе — бан на три месяца…
Unit’ы
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
|
|
Есть Unit1 и Unit2 как сделать что бы они были видны ДРУГ ДРУГУ ? |
|
Profi |
|
|
В секции Uses в каждом прописать другой. |
|
uk- |
|
|
Про ошибку оворит Счас скажу какая Добавлено 14.01.06, 15:07 Сообщение отредактировано: uk- — 14.01.06, 15:08 |
volvo877 |
|
|
«Circular unit reference»? Ты должен хотя бы в одном модуле подключать второй в разделе Implementation… Если оба модуля подключают друг друга в разделе Interface — это недопустимо… |
|
uk- |
|
|
В Unit1 написал implementation uses Unit2; А в Unit2 написал interface uses Unit1; И Unit2 не видит unit1 Добавлено 14.01.06, 15:29 implementation uses Code; Сообщение отредактировано: uk- — 14.01.06, 15:29 |
|
HyperTerraSoft |
|
|
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation uses Unit2; {$R *.dfm} end. unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm2 = class(TForm) private { Private declarations } public { Public declarations } end; var Form2: TForm2; implementation uses Unit1; {$R *.dfm} end. Сообщение отредактировано: HyperTerraSoft — 14.01.06, 17:59 |
|
uk- |
|
|
Unit2 не видет Unit1 |
|
Profi |
|
|
Цитата uk- @ 14.01.06, 18:08 Unit2 не видет Unit1 А зачем тебе вообще эта перекрестная связь нужна? |
|
HyperTerraSoft |
|
|
Цитата uk- @ 14.01.06, 18:08 Unit2 не видет Unit1
А что ты понимашь под словом «видит»?? ЗЫ. Никогда не называй себя идиотом, — потом от этой клички очень трудно отделаться! |
|
uk- |
|
|
Цитата А что ты понимашь под словом «видит»??
Понял Сенкс Цитата ЗЫ. Никогда не называй себя идиотом, — потом от этой клички очень трудно отделаться!
Я не назвал, а предположил.. |
|
HyperTerraSoft |
|
|
Все гиниальное — просто! |
|
Демо |
|
|
Достаточно функцию описать в секции interface, определить в секции implementation, и ссылку на модуль сделать либо в секции interface, либо в секции implementation другого модуля: unit Unit2; interface function Test: Boolean; implementation function Test: Boolean; begin Result := False; end; end. unit Unit3; interface uses Windows; implementation uses Unit2; procedure MyProc; begin if Test then MessageBox(0,’True’,’Внимание’,MB_OK) else MessageBox(0,’False’,’Внимание’,MB_OK) end; end. |
|
HyperTerraSoft |
|
|
Ну, это уже как вариант — человек просто не знал, как сделать, чтобы юниты видели друг друга! |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- Delphi: Общие вопросы
- Следующая тема
[ Script execution time: 0,0358 ] [ 16 queries used ] [ Generated: 9.02.23, 16:49 GMT ]
Fatal error unit1 pas 7 circular unit reference to unit1
Здравствуйте. Вот такая проблема — Дельфи не дает двум модулям видеть друг друга, вроде с помощью директив это должно исправляться, сделал их даже в двух вариантах, но Дельфи все равно не пропускает.
————— Unit1 —————-
<$IFNDEF flag1>
<$DEFINE flag1>
unit Map;
interface
uses Graphics, Windows <$IFNDEF flag2>, Unit2<$ENDIF>;
.
Выдается ошибка [Fatal Error] Unit1.pas: Circular unit reference to «Unit1»

Johnmen © ( 2007-07-03 14:21 ) [1]
Circular unit reference + F1

Dimaxx © ( 2007-07-03 14:25 ) [2]
А без DEFINE нормально работает? И зачем нужны они? Пусть себе ссылки на модули работают постоянно, а не только при наличии флагов.

Сергей М. © ( 2007-07-03 14:26 ) [3]
> Дельфи не дает двум модулям видеть друг друга
Не вижу здесь никакого «друг друга».
Задумано тобой так — либо первый использует второй, либо второй использует первый, в зависимости от определенности flag1 или flag2.
Но flag1 не видим за пределами Unit2, а flag2 — соответственно за пределами Гтше1. Оттого и проблема.
Решается просто — убираются директивы DEFINE, а flag1 или flag2 указываются в conditional defines на уровне проекта в целом (см. свойства проекта)

Gydvin © ( 2007-07-03 14:28 ) [4]
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
< Private declarations >
public
< Public declarations >
end;
var
Form1: TForm1;
implementation
uses
unit3;
procedure TForm1.Button1Click(Sender: TObject);
begin
MyCoolProcedure;
end;
unit Unit3;
interface
uses
Windows;
procedure MyCoolProcedure;
begin
form1.Caption:=»ddd»;
end;
end.
в интерфейсе unit1 описан класс, использующий Unit2, а в интерфейсе unit2 описан класс, используюший unit1. Если uses ставить а Implementetion, не прокатывает

Германн © ( 2007-07-03 14:39 ) [6]
> kilya © (03.07.07 14:35) [5]
>
> в интерфейсе unit1 описан класс, использующий Unit2, а в
> интерфейсе unit2 описан класс, используюший unit1.
Облом. 🙁
Хотя бы одно из этих описаний вынеси в третий модуль. Или объедини оба модуля в один, если это возможно.

Gydvin © ( 2007-07-03 14:50 ) [7]
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, unit2, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
< Private declarations >
public
< Public declarations >
end;
var
Form1: TForm1;
procedure TForm1.Button1Click(Sender: TObject);
var
a: class_1;
begin
a := class_1.create;
a.Free;
end;
type
class_1 = class
private
public
constructor create;
end;
type
class_3 = class
private
public
procedure mess_1;
constructor create;
constructor class_1.create;
var
a: class_2;
begin
a := class_2.create;
a.mess_2;
a.Free;
end;
procedure class_3.mess_1;
begin
MessageboxA(0, «1», «», 0);
end;
unit Unit3;
interface
uses
windows;
type
class_2 = class
private
public
constructor create;
procedure mess_2;
end;
constructor class_2.create;
var
a: class_3;
begin
a := class_3.create;
a.mess_1;
a.Free;
end;
procedure class_2.mess_2;
begin
MessageboxA(0, «2», «», 0);
end;
Что я делаю не так? unit2 и unit3 «видят друг друга

kilya © ( 2007-07-03 15:01 ) [8]
> Что я делаю не так? unit2 и unit3 «видят друг друга
————————
unit Unit2;

Gydvin © ( 2007-07-03 15:18 ) [9]
unit Unit2;
interface
uses windows;
type
class_1=class
public
procedure mess;
end;
implementation
uses
unit3;
uses windows, unit2;
type
class_2=class
field: class_1;
public
procedure mess ;
end;
implementation
> и те?
в твоем классе class_1 добавь поле типа class_2

Gydvin © ( 2007-07-03 15:40 ) [11]
Ух ты какой хитрый )))
У тя в любом случае ничего не выйдет. Классы ссылаясь друг на друга создавали бы бесконечное множество экземпляров друг друга в геометрической прогресии, Что в конечном итоге вызовет оут оф мемори.
Во всяком случае мастера, возможно, более точно опишут эту ситуевину, или поправят меня, еслия не прав.

Плохиш © ( 2007-07-03 15:41 ) [12]
> kilya © (03.07.07 14:35) [5]
> в интерфейсе unit1 описан класс, использующий Unit2, а в
> интерфейсе unit2 описан класс, используюший unit1. Если
> uses ставить а Implementetion, не прокатывает
Рекомендую поменять консерваторию.

kilya © ( 2007-07-03 15:50 ) [13]
> Классы ссылаясь друг на друга создавали бы бесконечное множество
> экземпляров
насколько я понимаю, описывая field: TClass никаких экземпляров не создается, т.к. field хранит всего лишь адрес, а не сам объект (помоему в Делфи так, в отличии от c++)

kilya © ( 2007-07-03 16:15 ) [14]
> Решается просто — убираются директивы DEFINE, а flag1 или
> flag2 указываются в conditional defines на уровне проекта
> в целом (см. свойства проекта)
не получается что-то так 🙁
Наверное в делфи так незя :((
> Наверное в делфи так незя
Изволь выражаться конкретнее и понятнее .

kilya © ( 2007-07-03 16:31 ) [16]
> Изволь выражаться конкретнее и понятнее .
в uses»ы интерфесов двух модулей указывать включение друг друга

Сергей М. © ( 2007-07-03 16:39 ) [17]
> в uses»ы интерфесов двух модулей указывать включение друг
> друга
>
Да, это действительно «незя».
А оно и нафих не нужно, да и, судя по примеру кода, содержащего условные дефиниции, преследовал ты явно иные цели.
А ограничение циркулярной ссылки с легкостью снимается разносом uses-ссылок по разделам interface и implementation.

kilya © ( 2007-07-03 17:53 ) [18]
Сергей М., ну скажи мне, как ты тут разнесешь uses-ссылки?
unit Unit1; // главный модуль приложения
interface
uses unit2;
.
———————————
unit Unit2;
interface
uses uni3;
type
class_1 = class // класс, содержащий объект класса class_2
field: class_2;
end;
.
—————
unit Unit3;
interface
uses Unit2;
type
class_2 = class
parent: class_1; // адрес родителя class_1
end;
.
—————

Сергей М. © ( 2007-07-04 08:28 ) [19]
А так ли уж необходима глобальная область видимости обоих идентификаторов — class_1 и class_2 ?
Если нужна, то почему не поместить их декларацию в интерфейсный раздел одного и того же юнита ?
Если не нужна, то почему не поместить декларацию одного из идентификаторов в раздел имплементации соотв.юнита и сослаться на юнит с декларацией другого идентификатора в uses раздела имплементации этого юнита, т.е. понизить область видимости одного из идентификаторов до локальной ?

kilya © ( 2007-07-04 13:32 ) [20]
> А так ли уж необходима глобальная область видимости обоих
> идентификаторов — class_1 и class_2 ?
Нужна
> Если нужна, то почему не поместить их декларацию в интерфейсный
> раздел одного и того же юнита ?
Хорошо все в одном интерфейсе:
class_1=class
field: class_2;
end;
class_2=class
parent:class_1;
end;
Так класс class_1 тоже не видит класс class_2 🙂
Вот так чтоли сделать?:
TNewtype = ^class_2;
class_1=class
field: TNewtype;
end;
class_2=class
parent:class_1;
end;
Так видит :/

Плохиш © ( 2007-07-04 13:34 ) [21]
> kilya © (04.07.07 13:32) [20]
> TNewtype = ^class_2;
> class_1=class
> field: TNewtype;
> end;
> class_2=class
> parent:class_1;
> end;
Афигенное знание основ 🙁
class_2=class;
class_1=class
field: TNewtype;
end;
class_2=class
parent:class_1;
end;

Плохиш © ( 2007-07-04 13:35 ) [22]

kilya © ( 2007-07-04 14:19 ) [23]
Источник
Fatal error unit1 pas 7 circular unit reference to unit1

Джо © ( 2008-01-01 23:59 ) [1]
Объявить переменную в секции implementation, включить этот юнит (uses) в другой.

DmT ( 2008-01-02 00:10 ) [2]
теперь выдал ошибку
[Fatal Error] Unit1.pas(7): Circular unit reference to «Unit1»

© ( 2008-01-02 00:13 ) [3]
> [0] DmT (01.01.08 23:54)
> Как получить доступ на чтение к переменной из другого юнита?
Не совсем понятно. т.е. хочется ТОЛЬКО чтение или.
Если неважно (и чтение и запись) — то uses»ма пользуйся, иначе уточни вопрос.
> [2] DmT (02.01.08 00:10)
Уточни вопрос.
> Circular unit reference to «Unit1»
Зацикливание. у тебя ссылка стоит на модуль в котором есть ссылка на этот модуль.

© ( 2008-01-02 00:15 ) [4]
unit Unit1
interfase
var T: Integer;
function GetT: Integer;
begin
Result:=T; читаем переменную из unit1
end;
> Джо © (01.01.08 23:59) [1]
>
> Объявить переменную в секции implementation
Хм.

Германн © ( 2008-01-02 00:38 ) [6]
> © (02.01.08 00:15) [4]
>
>
Не надо без нужды прописывать другой модуль в interface uses. Из-за этого и получается «Circular reference».

korneley © ( 2008-01-02 00:56 ) [7]
> Не надо без нужды прописывать другой модуль в interface
> uses.
Беда D7 + пользование «File» -> «Use Unit» или всё-таки это к разработчикам?

Германн © ( 2008-01-02 01:01 ) [8]
> korneley © (02.01.08 00:56) [7]
>
>
> > Не надо без нужды прописывать другой модуль в interface
> > uses.
>
> Беда D7 + пользование «File» -> «Use Unit» или всё-таки
> это к разработчикам?
>
Не знаю Д7. В Д4, Д6 если я забыл сам указать в uses нужный модуль, то при компиляции мне всегда выдается сообщение с предложением включить его туда. И когда я соглашаюсь, он прописывается в implementation uses.

korneley © ( 2008-01-02 01:11 ) [9]
> И когда я соглашаюсь, он прописывается в implementation
> uses
Это если ты пользуешь автосоздаваемые средой переменные 🙂 Опять к Остеру не ходи. Или к АП.
> Это если ты пользуешь автосоздаваемые средой переменные
> 🙂
Не понял. Но возможно ты и прав. Во всяком случае в ситуации © (02.01.08 00:15) [4] я очень редко когда забываю сам ручками включить модуль в uses. Тем более, что я хоть «глобальных переменных» и не чураюсь, но пользую их крайне редко.

DmT ( 2008-01-02 13:16 ) [11]
я не могу обойтись без uses ссылок друг на друга
в С++Builder 6 можно в обоих модулях написать
#include «Unit1.h»
#include «Unit2.h»
и всё компилится
никаких циркуляров

Сергей М. © ( 2008-01-02 14:10 ) [12]
> не могу обойтись без uses ссылок друг на друга

© ( 2008-01-02 17:27 ) [13]
> [6] Германн © (02.01.08 00:38)
> Не надо без нужды прописывать другой модуль в interface uses.
Здесь согласен, а здесь
> Из-за этого и получается «Circular reference».
это получается из-за другого. прокладка? 🙂
Навсяк для автора:
В делфи оператор uses может использоваться в двух местах в интерфейсной части модуля и в части реализации(implementation)
Возмем к примеру два модуля, например из [4]. В модуле Unit2 нам необходимо использовать модуль Unit1. т.е. нам нужна всего лишь переменная T. Смотрим. она(переменная) нам в unit2 в интерфейсной части не нужна, тогда нет необходимости подключать unit1(как я сделал в примере) в интерфейсную часть, а нужно было в implementation.
Другая ситуация когда необходимо в interfase подключать:
В модуле unit1 в интерфейсе обявлен тип, этот тип нужно использовать в объявлении нового класса в интерфейсе модуля unit2. Пример:
unit Unit1
interfase
type MyString = String[15];
var T: Integer;
type MyClass = class
Name: MyString;
.
end;
function GetT: Integer;
begin
Result:=T; читаем переменную из unit1
end;
А в [4] второй юнит должен быть таким:
unit unit2;
interfase
.
function GetT: Integer;
begin
Result:=T; читаем переменную из unit1
end;

MsGuns © ( 2008-01-02 19:49 ) [14]
Вот несколько принципов, соблюдая которые навсегда избавишься от проблем «видимости»:
1. Объекты, переменные, методы ОБЩЕГО ПОЛЬЗОВАНИЯ всегда размещать в датамодуле, причем сам код датамодуля не должен «ведать» ни о каких переменных извне — все, что ему надо, должно передаваться в параметрах.
Ссылку на датамодуль располагать в инфтерфейсной части всех юнитов — «клиентов», там, где перечисляются VCL-ные юниты. Датамодуль так же, как и гл.формы, должен быть включен в список автосоздаваемых.
2. Главная форма не должна обращаться ни к какому юниту, кроме датамодуля, ПО ИМЕНИ. Только по явной ссылке, используя разыменование типа. Уместно иногда вместо прямых вызовов внешних процедур использовать сообщения — при этом нет необходимости делать методы сторонних юнитов видимыми (uses в implementation) — такая технология удобна, например, при реализации общего функционала в MDI — приложениях.
3. «Дочерние» формы могут обращаться к переменным и методам Главной формы так же, как к датамодулю, для чего имя инита гл.формы также располагается в интерфейсной части uses. Все «дочерние» формы должны быть исключены из списка автосоздаваемых.
4. Не следует хранить данные, относящиеся к какому-то объекту (например, доч.форме), вне этого объекта. В сторонние методы, обрарабывающие объект, адрес на него передавать параметром.
5. Объекты уничтожает тот, что его создает.
6. Объект никогда не уничтожается в процедуре (функции), которой он передается как параметр (точнее, ссылка на него)
7. Объект, созданный в процедуре, не должен никуда передаваться, а используется лишь как временный участок памяти, очвобождаемый по выходу из процедуры.
Это схема, конечно, не является догмой, но новичкам позволяет избежать массу ошибок.
Источник
Модератор: Модераторы
странная ошибка Circular unit reference [решено]
При компиляции получаю ошибку: Fatal: Circular unit reference between SpecialProcs and Unit1
При этом в SpecialProcs имеется uses Unit1, а вот в Unit1 нет uses SpecialProcs. Честно говоря, озадачен и прошу помощь зала.
Версия Lazarus 1.0.10
Последний раз редактировалось trengtor 15.07.2013 11:12:33, всего редактировалось 1 раз.
-
trengtor - новенький
- Сообщения: 77
- Зарегистрирован: 03.05.2013 08:57:43
- Откуда: Москва
Re: странная ошибка Circular unit reference
Zak » 14.07.2013 00:11:36
Странно конечно, но как вариант:
— в SpecialProcs, определение uses Unit1 перенести из секции interface в implementation
— попробуйте «собрать», а не запустить проект. возможно связи восстановятся, если что мудрили с файлами
И еще: какой результат нужен-то?
перекрестная связь между юнитами? или наоборот избавиться от неё?
- Zak
- новенький
- Сообщения: 31
- Зарегистрирован: 16.06.2013 07:24:39
- Откуда: морозная Сибирь
Re: странная ошибка Circular unit reference
trengtor » 14.07.2013 01:10:12
Перекрестные связи не требуются. Перенес uses в impementation, сделал пересборку. Получил новую ошибку, уже в unit1:
unit1.pas(66,15) Error: Forward declaration not solved «TForm1.SMC_OffLightChangeBounds(TObject);»
me в восхищении…
Добавлено спустя 11 часов 37 минут 58 секунд:
Все, разобрался со 2-й ошибкой. В форме появился «левый» обработчик.
-
trengtor - новенький
- Сообщения: 77
- Зарегистрирован: 03.05.2013 08:57:43
- Откуда: Москва
Re: странная ошибка Circular unit reference
zub » 14.07.2013 22:05:10
>>При этом в SpecialProcs имеется uses Unit1, а вот в Unit1 нет uses SpecialProcs. Честно говоря, озадачен и прошу помощь зала.
Ничего удивительного. видимо uses Unit1 есть в других юнитах подключеных в SpecialProcs. Циклическая ссылка она необязательно когда 2 юнита ссылаются друг на друга, зацикленность может быть через длинную цепочку юнитов, при этом сообщение об ошибке не очень информативное и разрулить такую зацикленность довольно трудно
- zub
- долгожитель
- Сообщения: 2859
- Зарегистрирован: 14.11.2005 23:51:26
-
- Профиль
- Сайт
Re: странная ошибка Circular unit reference
trengtor » 15.07.2013 11:12:16
Спасибо, теперь все понятно.
-
trengtor - новенький
- Сообщения: 77
- Зарегистрирован: 03.05.2013 08:57:43
- Откуда: Москва
Вернуться в Lazarus
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8
← →
DmT
(2008-01-01 23:54)
[0]
сабж
← →
Джо ©
(2008-01-01 23:59)
[1]
Объявить переменную в секции implementation, включить этот юнит (uses) в другой.
← →
DmT
(2008-01-02 00:10)
[2]
теперь выдал ошибку
[Fatal Error] Unit1.pas(7): Circular unit reference to «Unit1»
← →
{RASkov} ©
(2008-01-02 00:13)
[3]
> [0] DmT (01.01.08 23:54)
> Как получить доступ на чтение к переменной из другого юнита?
Не совсем понятно…. т.е. хочется ТОЛЬКО чтение или….
Если неважно (и чтение и запись) — то uses»ма пользуйся, иначе уточни вопрос….
> [2] DmT (02.01.08 00:10)
Уточни вопрос….
> Circular unit reference to «Unit1»
Зацикливание…. у тебя ссылка стоит на модуль в котором есть ссылка на этот модуль…
← →
{RASkov} ©
(2008-01-02 00:15)
[4]
unit Unit1
interfase
var T: Integer;
implementation
……
———————————
unit unit2;
interfase
uses unit1;
implementation
function GetT: Integer;
begin
Result:=T; читаем переменную из unit1
end;
← →
Германн ©
(2008-01-02 00:36)
[5]
> Джо © (01.01.08 23:59) [1]
>
> Объявить переменную в секции implementation
Хм.
← →
Германн ©
(2008-01-02 00:38)
[6]
> {RASkov} © (02.01.08 00:15) [4]
>
>
Не надо без нужды прописывать другой модуль в interface uses. Из-за этого и получается «Circular reference».
← →
korneley ©
(2008-01-02 00:56)
[7]
> Не надо без нужды прописывать другой модуль в interface
> uses.
Беда D7 + пользование «File» -> «Use Unit» или всё-таки это к разработчикам?
← →
Германн ©
(2008-01-02 01:01)
[8]
> korneley © (02.01.08 00:56) [7]
>
>
> > Не надо без нужды прописывать другой модуль в interface
> > uses.
>
> Беда D7 + пользование «File» -> «Use Unit» или всё-таки
> это к разработчикам?
>
Не знаю Д7. В Д4, Д6 если я забыл сам указать в uses нужный модуль, то при компиляции мне всегда выдается сообщение с предложением включить его туда. И когда я соглашаюсь, он прописывается в implementation uses.
← →
korneley ©
(2008-01-02 01:11)
[9]
> И когда я соглашаюсь, он прописывается в implementation
> uses
Это если ты пользуешь автосоздаваемые средой переменные 
← →
Германн ©
(2008-01-02 01:37)
[10]
> Это если ты пользуешь автосоздаваемые средой переменные
> 
Не понял. Но возможно ты и прав. Во всяком случае в ситуации {RASkov} © (02.01.08 00:15) [4] я очень редко когда забываю сам ручками включить модуль в uses. Тем более, что я хоть «глобальных переменных» и не чураюсь, но пользую их крайне редко.
← →
DmT
(2008-01-02 13:16)
[11]
я не могу обойтись без uses ссылок друг на друга
в С++Builder 6 можно в обоих модулях написать
#include «Unit1.h»
#include «Unit2.h»
и всё компилится
никаких циркуляров
← →
Сергей М. ©
(2008-01-02 14:10)
[12]
> не могу обойтись без uses ссылок друг на друга
unit1
interface
uses unit2
unit2
implementation
uses unit1
← →
{RASkov} ©
(2008-01-02 17:27)
[13]
> [6] Германн © (02.01.08 00:38)
> Не надо без нужды прописывать другой модуль в interface uses.
Здесь согласен, а здесь
> Из-за этого и получается «Circular reference».
это получается из-за другого…… прокладка? 
Навсяк для автора:
В делфи оператор uses может использоваться в двух местах в интерфейсной части модуля и в части реализации(implementation)
Возмем к примеру два модуля, например из [4]. В модуле Unit2 нам необходимо использовать модуль Unit1…. т.е. нам нужна всего лишь переменная T… Смотрим…. она(переменная) нам в unit2 в интерфейсной части не нужна, тогда нет необходимости подключать unit1(как я сделал в примере) в интерфейсную часть, а нужно было в implementation….
Другая ситуация когда необходимо в interfase подключать:
В модуле unit1 в интерфейсе обявлен тип, этот тип нужно использовать в объявлении нового класса в интерфейсе модуля unit2…. Пример:
unit Unit1
interfase
type MyString = String[15];
var T: Integer;
implementation
......
--------------------------------
unit unit2;
interfase
uses unit1;
type MyClass = class
Name: MyString;
.........
end;
implementation
function GetT: Integer;
begin
Result:=T; читаем переменную из unit1
end;
А в [4] второй юнит должен быть таким:unit unit2;
interfase
..............
implementation
uses unit1;
function GetT: Integer;
begin
Result:=T; читаем переменную из unit1
end;
← →
MsGuns ©
(2008-01-02 19:49)
[14]
Вот несколько принципов, соблюдая которые навсегда избавишься от проблем «видимости»:
1. Объекты, переменные, методы ОБЩЕГО ПОЛЬЗОВАНИЯ всегда размещать в датамодуле, причем сам код датамодуля не должен «ведать» ни о каких переменных извне — все, что ему надо, должно передаваться в параметрах.
Ссылку на датамодуль располагать в инфтерфейсной части всех юнитов — «клиентов», там, где перечисляются VCL-ные юниты. Датамодуль так же, как и гл.формы, должен быть включен в список автосоздаваемых.
2. Главная форма не должна обращаться ни к какому юниту, кроме датамодуля, ПО ИМЕНИ. Только по явной ссылке, используя разыменование типа. Уместно иногда вместо прямых вызовов внешних процедур использовать сообщения — при этом нет необходимости делать методы сторонних юнитов видимыми (uses в implementation) — такая технология удобна, например, при реализации общего функционала в MDI — приложениях.
3. «Дочерние» формы могут обращаться к переменным и методам Главной формы так же, как к датамодулю, для чего имя инита гл.формы также располагается в интерфейсной части uses. Все «дочерние» формы должны быть исключены из списка автосоздаваемых.
4. Не следует хранить данные, относящиеся к какому-то объекту (например, доч.форме), вне этого объекта. В сторонние методы, обрарабывающие объект, адрес на него передавать параметром.
5. Объекты уничтожает тот, что его создает.
6. Объект никогда не уничтожается в процедуре (функции), которой он передается как параметр (точнее, ссылка на него)
7. Объект, созданный в процедуре, не должен никуда передаваться, а используется лишь как временный участок памяти, очвобождаемый по выходу из процедуры.
Это схема, конечно, не является догмой, но новичкам позволяет избежать массу ошибок.
The declaration of the TMessageClass class does not need to know the specifics of how the TChatItemClass class is declared, only that it is a class type, so use a forward declaration to break the circular unit dependancy of the two interface sections, eg:
unit StackWeb.MessageClass;
interface
{uses
StackWeb.ChatItemClass;}
type
TChatItemClass = class; // <-- HERE
TMessageClass = class(TCardDefault)
private
FChat : TChatItemClass;
public
property chat : TChatItemClass read FChat write FChat;
end;
implementation
uses
StackWeb.ChatItemClass; // <-- MOVED HERE
...
end.
unit
StackWeb.ChatItemClass;
interface
uses
StackWeb.MessageClass;
type
TChatItemClass = class(TClassStandardList<TMessageClass>)
private
FMessages : TArray<TMessageClass>;
public
property messages : TArray<TMessageClass> read FMessages write FMessages;
end;
...
end.
This scenario is actually covered in Delphi’s documentation:
Classes and Objects (Delphi): Forward Declarations and Mutually Dependent Classes
If the declaration of a class type ends with the word
classand a semicolon — that is, if it has the formtype className = class;with no ancestor or class members listed after the word
class, then it is a forward declaration. A forward declaration must be resolved by a defining declaration of the same class within the same type declaration section. In other words, between a forward declaration and its defining declaration, nothing can occur except other type declarations.Forward declarations allow mutually dependent classes. For example:
type TFigure = class; // forward declaration TDrawing = class Figure: TFigure; // ... end; TFigure = class // defining declaration Drawing: TDrawing; // ... end;Do not confuse forward declarations with complete declarations of types that derive from System.TObject without declaring any class members.
type TFirstClass = class; // this is a forward declaration TSecondClass = class // this is a complete class declaration end; TThirdClass = class(TObject); // this is a complete class declaration
Форум программистов Vingrad
| Модераторы: Snowy, MetalFan, bems, Poseidon |
Поиск: |
![]() ![]()
|
|
Опции темы |
| d10gtr |
|
||
|
Новичок Профиль Репутация: нет
|
Создаю Form1 (Unit1) и form2 (Unit2)
пишу в Unit1 : Так же с Unit2 когда пишу Form2…. Я же подключил 2 формы друг к другу… Ещё в Unit1 В разделе Uses нажимаю на Unit2 удерживая CTRL… А должно открыться окно с unit2 Это сообщение отредактировал(а) Alexeis — 26.10.2007, 11:02 |
||
|
|||
| volvo877 |
|
||
Эксперт Профиль Репутация: 9
|
Потому что нельзя подключать 2 юнита друг у другу в секции Interface… Подключи один из них в секции Implementation, или переделывай структуру программы, если не получается это сделать… |
||
|
|||
| ivan219 |
|
||
Эксперт Профиль
Репутация: 5
|
Это сообщение отредактировал(а) ivan219 — 26.10.2007, 19:57 ——————— Мой первый сайт и моя первая программа!!!!! |
||
|
|||
| volvo877 |
|
||
Эксперт Профиль Репутация: 9
|
ivan219, в результате — Circular Unit Reference… Я написал выше, что подключать надо в разделе Implementation! |
||
|
|||
| ivan219 |
|
||
Эксперт Профиль
Репутация: 5
|
Вот глова дубовая ——————— Мой первый сайт и моя первая программа!!!!! |
||
|
|||
| mrbrooks |
|
||
трололомен Профиль
Репутация: нет
|
Дельфятина вещь умная — для новичков рекомендую Alt-F11 и никаких проблем. |
||
|
|||
![]() ![]()
|
| Правила форума «Delphi: Для новичков» | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) |
| 0 Пользователей: |
| « Предыдущая тема | Delphi: Для новичков | Следующая тема » |















)



















