Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизВидимость переменных в разных модулях Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.073 c