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

Вниз

Видимость переменных в разных модулях   Найти похожие ветки 

 
Pcrepair ©   (2012-06-07 11:39) [0]

Добрый день
Есть
Unit1 - основной модуль, содержит форму
unit2 - без формы, содержит процедуру, вызываемую из Unit1
Data: string; - глобальная переменная для хранения текста

Если разместить Data в модуль Unit2 перед implementation то все нормально работает, Data доступна подпрограммам и из Unit1 и Unit2

Если разместить Data в модуль Unit1 перед implementation, то из Unit2 она не доступна

уже размещал Data в секцию public в Unit1 и вводил Unit1 в секцию uses unit2, ничего не помогает

public
 var
   Data: string;
 end;

Кто подскажет в чем дело? нужно разместить переменную в основном модуле, но чтоб она была доступна в подключаемых модулях


 
Юрий Зотов ©   (2012-06-07 11:44) [1]

1. Размещаете переменную в секции interface основного модуля
2. В подключаемых модулях пишете uses unit1 в секции implementation


 
Sha ©   (2012-06-07 11:46) [2]

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


 
Sha ©   (2012-06-07 11:47) [3]

> Юрий Зотов ©   (07.06.12 11:44) [1]

[2] - это не тебе , разумеется )


 
Pcrepair ©   (2012-06-07 12:17) [4]


> Вообще-то, так делать плохо

что именно плохо?
использовать несколько модулей а может ГлобПерем?


 
robt   (2012-06-07 12:26) [5]


> нужно разместить переменную в основном модуле, но чтоб она
> была доступна в подключаемых модулях

офигеть вопросы пошли, первая глава любой книги "дельфи для чайников"


 
Pcrepair ©   (2012-06-07 12:30) [6]

какой например? а то у меня этих книжек штук надцать но нигде в первой главе, да и впоследующих то же нет конкретного указания на правильный способ
ну может где то мельком и упоминается, без комментарием как правильно как неправильно


 
robt   (2012-06-07 12:35) [7]


> Pcrepair ©   (07.06.12 12:30) [6]

да быть такого не могёт !!!
все что в interface видно в других модулях, все что implementation в текущем


 
ProgRAMmer Dimonych ©   (2012-06-07 12:39) [8]

> [7] robt   (07.06.12 12:35)

Как ни странно, тоже не припомню книжки, где бы это было написано так, чтобы бросаться в глаза. Сам разбирался с этим простым правилом по help"у, когда понадобилось. Но для этого надо, чтобы такой вопрос возник, а до того можно в Unit1.pas глобальные переменные создавать - и ни разу не задуматься.


 
DVM ©   (2012-06-07 12:40) [9]


> Pcrepair ©   (07.06.12 12:17) [4]


>  а может ГлобПерем?

ну вобщем то, если в процессе работы программы значение глобальной переменной будет меняться более одного раза (желательно вообще, чтобы этот один раз был при старте программы), то такие переменные лучше не использовать.


 
robt   (2012-06-07 12:40) [10]

читай "старые" книги, по делфе 3-5 тогда еще гугла не было...


 
Pcrepair ©   (2012-06-07 12:42) [11]

ну это просто по ошибке в уните2 не там указал в uses унит1


 
AV ©   (2012-06-07 12:43) [12]

а если есть, допустим Http консоль управления программой, и продюсер страниц, и еще некоторые модули
все должны знать IP компа, что бы генерировать ссылки, приводящие опять же на себя.
Тогда без глобальной никак, имхо.
Не писать же класс с единственным методом GetMyIPAddr


 
AV ©   (2012-06-07 12:45) [13]


> если в процессе работы программы значение глобальной переменной
> будет меняться более одного раза (

по голове не бить :) всего 3 минуты прошло, не успел :)


 
robt   (2012-06-07 12:45) [14]


> DVM ©   (07.06.12 12:40) [9]

не, неправильно, можно и нужно, главно осознавать чОпроисходит
форма, это собственно и есть одна большая глобальная переменная


 
Pcrepair ©   (2012-06-07 12:46) [15]


> ну вобщем то, если в процессе работы программы значение
> глобальной переменной будет меняться более одного раза (желательно
> вообще, чтобы этот один раз был при старте программы), то
> такие переменные лучше не использовать.


вообще значения этой ПЕРЕм будут менятся мульены раз в процессе работы программы
ГлобПерем служит типа хранилищем данных по типу стека:
одна процедура взвла данные из , обработала и назад положила
потом следующая процедура
и так постоянно

а какой еще вариант? может сделать что то вроде буфера? типа отдельного юнита с процедурой?


 
robt   (2012-06-07 12:52) [16]


> Pcrepair ©   (07.06.12 12:46) [15]

[14]


 
Anatoly Podgoretsky ©   (2012-06-07 13:20) [17]


> Pcrepair ©   (07.06.12 12:30) [6]
> какой например? а то у меня этих книжек штук надцать

Не в коня корм


 
AV ©   (2012-06-07 14:05) [18]

подозреваю, что надо из нескольких мест следить за данными?

накидал вот тут..
TDataProducer - класс, имеющий метод AddProc, который добавляет метод к уведомлению об изменении данных.
Кто заинтересован в изменении данных - вызывает AddProc, подавая туда свой метод. Как данные изменятся - заинтересованный будет уведомлен.
Только менять данные надо аккуратно - иначе опять вызовутся уведомления
т.е. надо грамотно написать SetData

type
 TDataProducerNotify = procedure (Sender: TObject; const sOldData, sNewData: string) of object;
 TDataProducerNotify2 = procedure (Sender: TObject; const Idx: integer; sOldData, sNewData: string) of object;
 TDataProducer = class
 private
   FData: string;
   FMyOnWriteData: TDataProducerNotify;
   FListOnWriteData: TList;
   procedure SetData(const Value: string);
 public
   constructor Create;
   procedure AddProc(Proc: TDataProducerNotify2);
   property Data:string read FData write SetData;
   property OnWriteData:TDataProducerNotify read FMyOnWriteData write FMyOnWriteData;
 end;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   procedure FormCreate(Sender: TObject);
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private    { Private declarations }
 public     { Public declarations }
   DP: TDataProducer;
   procedure DPN1(Sender: TObject; const sOldData, sNewData: string);
   procedure DPN2(Sender: TObject; const Idx: integer; sOldData, sNewData: string);
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

{ TDataProducer }

procedure TDataProducer.AddProc(Proc: TDataProducerNotify2);
begin
 FListOnWriteData.Add(addr(Proc));
end;

constructor TDataProducer.Create;
begin
 FListOnWriteData := TList.Create;
end;

procedure TDataProducer.SetData(const Value: string);
var
 i: Integer;
 P: TDataProducerNotify2;
 M: TMethod;
begin
 if Assigned(FMyOnWriteData) then
    FMyOnWriteData(Self, FData, Value);
 for i := 0 to FListOnWriteData.Count - 1 do
 begin
   M.Code := FListOnWriteData.Items[i];
   M.Data := nil;
   P := TDataProducerNotify2( M );
   P(nil, i, FData, Value);
 end;
 FData := Value;
end;

{ TForm1 }

procedure TForm1.DPN1(Sender: TObject; const sOldData, sNewData: string);
begin
 ShowMessage(  sOldData + " -> " + sNewData);
end;

procedure TForm1.DPN2(Sender: TObject; const Idx: integer; sOldData, sNewData: string);
begin
 ShowMessageFmt("Notify number %d about: %s -> %s",[Idx, sOldData, sNewData]);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 DP := TDataProducer.Create;
 DP.OnWriteData := DPN1;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 DP.Data := DateTimeToStr(now);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 DP.AddProc(DPN2);
end;


 
DVM ©   (2012-06-07 15:21) [19]


> robt   (07.06.12 12:45) [14]
>
> > DVM ©   (07.06.12 12:40) [9]
>
> не, неправильно, можно и нужно, главно осознавать чОпроисходит
> форма, это собственно и есть одна большая глобальная переменная

За каким лешим разработчики VCL сделали автоматическую генерацию кода, содержащего глобальные переменные я не знаю, но прекрасно можно было обойтись и без них, как и  без кучи других, типа FormatSettings (которые кстати постепенно отмирают). Единственные глобальные переменные имеющие право на жизнь - это Application, Screen, Printer и т.д. и то последние могли бы быть полями первого. Итого остается Application.
Конечно, кто хочет - может использовать глобальные переменные, но нужды в них, особенно в последних версиях Delphi практически нет.


 
Pcrepair ©   (2012-06-07 15:34) [20]

кстати, так никто, даже толик, и не поведал: ну чем так ужастны глобальные переменные?
в книжках об этом, их ужастности, то же пишут, но совершенно бездоказательно


 
AV ©   (2012-06-07 15:41) [21]

http://www.gunsmoker.ru/2011/04/blog-post.html


 
Anatoly Podgoretsky ©   (2012-06-07 15:48) [22]

> DVM  (07.06.2012 15:21:19)  [19]

Создали для ламеров, как и многое другое


 
Anatoly Podgoretsky ©   (2012-06-07 15:49) [23]


> Pcrepair ©   (07.06.12 15:34) [20]
> кстати, так никто, даже толик, и не поведал: ну чем так
> ужастны глобальные переменные?
> в книжках об этом, их ужастности, то же пишут, но совершенно
> бездоказательно

Смотришь в книгу, видишь фигу


 
Юрий Зотов ©   (2012-06-07 15:53) [24]


> Pcrepair ©   (07.06.12 15:34) [20]
> чем так ужастны глобальные переменные?

Сами по себе - не ужасны. Но заставляют быть более аккуратным, потому что при неакуратности легко сделать ошибку, причем трудновыловимую. Вот пример (хотя и несколько надуманный, но все же).

unit unit1
interface
var MyVar: integer;  
end;

unit unit2
interface
var MyVar: integer;  
end;

unit unit3;
interface
uses unit1, unit2;
...
 MyVar := 1; // Это переменная из unit1;
end;

unit unit4;
interface
uses unit2, unit1;
...
 MyVar := 2; // А это переменная из unit2;
end;

Какая из двух MyVar будет использована - зависит от порядка перечисления модулей в uses. Теперь представьте, что разные модули писали разные программисты, и что второй из них, объявляя в своем модуле переменную MyVar, понятия не имел, что в другом модуле такая уже существует. В результате используется не та MyVar и программа работает, но не так, как надо. А в проекте десятки тысяч строк - попробуй вылови этот баг.


 
Pcrepair ©   (2012-06-07 16:10) [25]

вот именно, что тут, что у гани смокера одни надуманные примеры, да и доводы то же. все это прочитано и многое другое
вот если кто на реальных примерах указал, что при испоьзовании ГП:
- программа зависает
- перерасход памяти
- прочие плохие пришествия

тогда все эти утверждения что Гп - здло, не бы ли бы голословными


 
DVM ©   (2012-06-07 16:16) [26]


> Pcrepair ©   (07.06.12 16:10) [25]


> вот именно, что тут, что у гани смокера одни надуманные
> примеры, да и доводы то же.

Пример с доступом к глобальной переменной из нескольких потоков для тебя достаточно реальный? Как синхронизировать доступ?


 
AV ©   (2012-06-07 16:16) [27]

*аля АП
ну тогда ГП - это хорошо, используйте на здоровье


 
Pcrepair ©   (2012-06-07 16:51) [28]

DVM - нет, "Пример с доступом к глобальной переменной из нескольких потоков" для меня недостаточно реальный, поскольку на текущий момент в программе потоки не используются (к тому же кое-кто кое-где утверждает что ГМ + синхронизация = с потоками все хорошо)

у меня, получается, достаточно специфичная задача (и программа под нее), вот о ней в контексте использования ГП и можно подискутировать, конечно если тебе мнтересно


 
DVM ©   (2012-06-07 17:03) [29]


> Pcrepair ©   (07.06.12 16:51) [28]
> DVM - нет, "Пример с доступом к глобальной переменной из
> нескольких потоков" для меня недостаточно реальный, поскольку
> на текущий момент в программе потоки не используются

Мало ли что ты там НЕ ИСПОЛЬЗУЕШЬ, ты спросил, чем плохи глобальные переменные, тебе ответили.


>  кое-кто кое-где утверждает что ГМ + синхронизация = с потоками
> все хорошо)

Если синхронизировать то оно конечно хорошо, но как синхронизировать доступ к глобальной переменной будешь? Еще одной глобальной переменной-крит секцией? А если кто не знает, что обращение к твоей глобальной переменной надо делать через крит секцию и полезет напрямую?

А была бы приватным полем класса, синхронизировать доступ к публичному свойству представляющему поле через сеттер и геттер проще простого.


 
Юрий Зотов ©   (2012-06-07 17:06) [30]


> Pcrepair ©   (07.06.12 16:51) [28]

Примеров можно привести много. Переменная - указатель (или объект) объявлена в одном модуле, а работают с ней другие модули. В одном из них память освобождена (или объект уничтожен), а в другом переменная продолжает использоваться - возникает AV. И тоже фиг найдешь, где там она портится.

Впрочем, дело Ваше. Если гани смокер и другие, с многолетним опытом разработки, много раз наступавшие на разные грабли и уже знающие, как можно эти грабли обойти - если они для Вас не авторитеты, если их советы Вам кажутся надуманными - что ж, вперед.

Судя по заданному Вами вопросу, Ваш опыт разработки крайне мал (по крайней мере, на Delphi). Значит, рано или поздно на грабли Вы точно наступите - вот тогда и вспомните эти "надуманные советы".


 
Sha ©   (2012-06-07 18:42) [31]

> Pcrepair
> что тут, что у гани смокера одни надуманные примеры
> у меня, получается, достаточно специфичная задача

1. Ответы предназначены не только тебе, есть и другие начинающие.
2. Ты ждешь совет для задачи, о которой никто кроме тебя не знает?


 
Кщд   (2012-06-07 19:06) [32]

господа, вам не надоело кормить этого хамствующего тролля?)


 
Pcrepair ©   (2012-06-07 19:26) [33]

Удалено модератором



Страницы: 1 вся ветка

Текущий архив: 2013.03.22;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.06 c
15-1316779880
xayam
2011-09-23 16:11
2013.03.22
Физики ЦЕРН отменили предел скорости


15-1332164769
Empleado
2012-03-19 17:46
2013.03.22
Работа с формулами


2-1345262775
0?0
2012-08-18 08:06
2013.03.22
Не ожидать завершения процедуры.


15-1352647406
Аббат Пиккола
2012-11-11 19:23
2013.03.22
Вот кто решает, что вкус ароматизатора идентичен натуральному


15-1334781003
Юрий
2012-04-19 00:30
2013.03.22
С днем рождения ! 19 апреля 2012 четверг