![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ошибка Circular unit reference [D6, 95/98]
kilya © (2007-07-03 14:14:00)Здравствуйте. Вот такая проблема - Дельфи не дает двум модулям видеть друг друга, вроде с помощью директив это должно исправляться, сделал их даже в двух вариантах, но Дельфи все равно не пропускает.
-------------- 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'
kilya (2007-07-04 14:19:00) [1]гы )))
Плохиш (2007-07-04 13:35:00) [2]TNewtype --> class_2
Плохиш (2007-07-04 13:34:00) [3]
> 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;
kilya (2007-07-04 13:32:00) [4]> А так ли уж необходима глобальная область видимости обоих
> идентификаторов - 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 08:28:00) [5]А так ли уж необходима глобальная область видимости обоих идентификаторов - class_1 и class_2 ?
Если нужна, то почему не поместить их декларацию в интерфейсный раздел одного и того же юнита ?
Если не нужна, то почему не поместить декларацию одного из идентификаторов в раздел имплементации соотв.юнита и сослаться на юнит с декларацией другого идентификатора в uses раздела имплементации этого юнита, т.е. понизить область видимости одного из идентификаторов до локальной ?
kilya (2007-07-03 17:53:00) [6]Сергей М., ну скажи мне, как ты тут разнесешь 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-03 16:39:00) [7]
> в uses'ы интерфесов двух модулей указывать включение друг
> друга
>
Да, это действительно "незя".
А оно и нафих не нужно, да и, судя по примеру кода, содержащего условные дефиниции, преследовал ты явно иные цели.
А ограничение циркулярной ссылки с легкостью снимается разносом uses-ссылок по разделам interface и implementation.
kilya (2007-07-03 16:31:00) [8]
> Изволь выражаться конкретнее и понятнее ...
в uses'ы интерфесов двух модулей указывать включение друг друга
Сергей М. (2007-07-03 16:23:00) [9]
> Наверное в делфи так незя
Чего "незя" ?
Изволь выражаться конкретнее и понятнее ...
kilya (2007-07-03 16:15:00) [10]
> Решается просто - убираются директивы DEFINE, а flag1 или
> flag2 указываются в conditional defines на уровне проекта
> в целом (см. свойства проекта)
не получается что-то так :(
Наверное в делфи так незя :((
kilya (2007-07-03 15:50:00) [11]
> Классы ссылаясь друг на друга создавали бы бесконечное множество
> экземпляров
насколько я понимаю, описывая field: TClass никаких экземпляров не создается, т.к. field хранит всего лишь адрес, а не сам объект (помоему в Делфи так, в отличии от c++)
Плохиш (2007-07-03 15:41:00) [12]
> kilya © (03.07.07 14:35) [5]
> в интерфейсе unit1 описан класс, использующий Unit2, а в
> интерфейсе unit2 описан класс, используюший unit1. Если
> uses ставить а Implementetion, не прокатывает
Рекомендую поменять консерваторию...
Gydvin (2007-07-03 15:40:00) [13]Ух ты какой хитрый )))
У тя в любом случае ничего не выйдет. Классы ссылаясь друг на друга создавали бы бесконечное множество экземпляров друг друга в геометрической прогресии, Что в конечном итоге вызовет оут оф мемори.
Во всяком случае мастера, возможно, более точно опишут эту ситуевину, или поправят меня, еслия не прав.
kilya (2007-07-03 15:30:00) [14]ухх, сорри, пропустил строчку
------------------------
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:18:00) [15]и те?
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:01:00) [16]
> Что я делаю не так? 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 14:50:00) [17]
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 "видят друг друга
Германн (2007-07-03 14:39:00) [18]
> kilya © (03.07.07 14:35) [5]
>
> в интерфейсе unit1 описан класс, использующий Unit2, а в
> интерфейсе unit2 описан класс, используюший unit1.
Облом. :(
Хотя бы одно из этих описаний вынеси в третий модуль. Или объедини оба модуля в один, если это возможно.
kilya (2007-07-03 14:35:00) [19]в интерфейсе unit1 описан класс, использующий Unit2, а в интерфейсе unit2 описан класс, используюший unit1. Если uses ставить а Implementetion, не прокатывает
Gydvin (2007-07-03 14:28:00) [20]А так
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.