Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.059 c
15-1335608712
Труп Васи Доброго
2012-04-28 14:25
2013.03.22
Телефоноудлинитель


8-1230712152
Программер
2008-12-31 11:29
2013.03.22
Как узнать кодек и разрешение видеофайла?


15-1346364143
Artem
2012-08-31 02:02
2013.03.22
В Visual С++ автоматическая сборка мусора?


2-1342617866
Andrey K
2012-07-18 17:24
2013.03.22
Как в ShortCut вставить цифру с боковой клавиатуры.


15-1340137805
Юрий
2012-06-20 00:30
2013.03.22
С днем рождения ! 20 июня 2012 среда





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский