Форум: "Начинающим";
Текущий архив: 2007.07.29;
Скачать: [xml.tar.bz2];
Внизошибка Circular unit reference Найти похожие ветки
← →
kilya © (2007-07-03 14:14) [0]Здравствуйте. Вот такая проблема - Дельфи не дает двум модулям видеть друг друга, вроде с помощью директив это должно исправляться, сделал их даже в двух вариантах, но Дельфи все равно не пропускает.
-------------- Unit1 ----------------
{$IFNDEF flag1}
{$DEFINE flag1}
unit Map;
interface
uses Graphics, Windows {$IFNDEF flag2}, Unit2{$ENDIF};
...
{$ENDIF}
-------------- Unit2 ----------------
{$IFNDEF flag2}
{$DEFINE flag2}
unit Unit2;
interface
{$IFNDEF flag1}uses Unit1;{$ENDIF}
...
{$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 на уровне проекта в целом (см. свойства проекта)
т.е.
-------------- Unit1 ----------------
..
uses .. {$IFNDEF flag2}, Unit2{$ENDIF};
...
-------------- Unit2 ----------------
{$IFNDEF flag1}uses Unit1;{$ENDIF}
← →
Gydvin © (2007-07-03 14:28) [4]А так
unit Unit1;
interface
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;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
MyCoolProcedure;
end;
end.
unit Unit3;
interface
uses
Windows;
procedure MyCoolProcedure;
implementation
uses unit1;
procedure MyCoolProcedure;
begin
form1.Caption:="ddd";
end;
end.
← →
kilya © (2007-07-03 14:35) [5]в интерфейсе 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]
unit Unit1;
interface
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;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
a: class_1;
begin
a := class_1.create;
a.Free;
end;
end.
------------------------
unit Unit2;
interface
uses
windows;
type
class_1 = class
private
public
constructor create;
end;
type
class_3 = class
private
public
procedure mess_1;
constructor create;
end;
implementation
uses
unit3;
{ class_1 }
constructor class_1.create;
var
a: class_2;
begin
a := class_2.create;
a.mess_2;
a.Free;
end;
{ class_3 }
constructor class_3.create;
begin
///
end;
procedure class_3.mess_1;
begin
MessageboxA(0, "1", "", 0);
end;
end.
-----------------------------------------------
unit Unit3;
interface
uses
windows;
type
class_2 = class
private
public
constructor create;
procedure mess_2;
end;
implementation
uses
unit2;
{ class_2 }
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;
end.
-------------------------------------------
Что я делаю не так? unit2 и unit3 "видят друг друга
← →
kilya © (2007-07-03 15:01) [8]
> Что я делаю не так? unit2 и unit3 "видят друг друга
------------------------
unit Unit2;
interface
uses uni3;
type
class_1 = class
parent: class_2;
end;
...
---------------
unit Unit3;
interface
uses Unit2
type
field: class_1;
end;
...
--------------
← →
Gydvin © (2007-07-03 15:18) [9]и те?
unit Unit2;
interface
uses windows;
type
class_1=class
public
procedure mess;
end;
implementation
uses
unit3;
procedure bbb;
var
a:class_2;
begin
a:=class_2.Create;
end;
{ class_1 }
procedure class_1.mess;
begin
messageboxa(0,"1","",0);
end;
end.
--------------------
unit Unit3;
interface
uses windows, unit2;
type
class_2=class
field: class_1;
public
procedure mess ;
end;
implementation
{ class_2 }
procedure class_2.mess;
begin
field:=class_1.Create;
field.mess;
field.Free;
messageboxa(0,"2","",0);
end;
end.
← →
kilya © (2007-07-03 15:30) [10]ухх, сорри, пропустил строчку
------------------------unit Unit2;
interface
uses uni3;
type
class_1 = class
parent: class_2;
end;
...
---------------
unit Unit3;
interface
uses Unit2
type
class_2 = class // вот эту
field: class_1;
end;
...
--------------
> и те?
в твоем классе 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 на уровне проекта
> в целом (см. свойства проекта)
не получается что-то так :(
Наверное в делфи так незя :((
← →
Сергей М. © (2007-07-03 16:23) [15]
> Наверное в делфи так незя
Чего "незя" ?
Изволь выражаться конкретнее и понятнее ...
← →
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]TNewtype --> class_2
← →
kilya © (2007-07-04 14:19) [23]гы )))
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.07.29;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.049 c