Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.07.29;
Скачать: CL | DM;

Вниз

ошибка 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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.029 c
15-1183542702
IMHO
2007-07-04 13:51
2007.07.29
Delphi 5: заставка


15-1183447724
Fidel
2007-07-03 11:28
2007.07.29
АОН - определитель номера


2-1183457683
kilya
2007-07-03 14:14
2007.07.29
ошибка Circular unit reference


2-1183383561
авыф
2007-07-02 17:39
2007.07.29
MS SQL 2005


15-1183108690
Volcanic
2007-06-29 13:18
2007.07.29
Как объединить TreeView и ListView??