PDA

View Full Version : مشکل در تعریف متغیر استاتیک در دلفی 2009 ؟



BORHAN TEC
جمعه 20 شهریور 1388, 13:21 عصر
وقتی می خواهم در دلفی 2009 یک متغیر استاتیک تعریف کنم با خطا مواجه می شوم واین در حالی است که در دلفی 5 کد زیر به راحتی اجرا می شود ولی در دلفی 2009 این طور نیست. سوال این است که برای تبدیل این کد به دلفی 2009 باید چه کنم ؟


procedure TForm1.Button1Click(Sender: TObject);
const
bln : Boolean = false;
begin
bln := not bln;
if bln then
memo1.Hide
else
memo1.Show;
end;

با تشکر از همه دوستان عزیز !

جواد ملاولی
جمعه 20 شهریور 1388, 14:00 عصر
سلام. شما bln رو بصورت ثابت (const) تعریف کردید و در برنامه می خواید اون رو تغییر بدید؛ خوب معلومه که خطا میده. شما باید bln رو به عنوان متغیر تعریف کنید.
ضمن اینکه برای مخفی کردن و ظاهر کردن Memo اصلا احتیاجی به این کد ها نیست؛ فقط یک خط کد می خواد:

Memo1.Visible := not Memo1.Showing;

BORHAN TEC
جمعه 20 شهریور 1388, 20:23 عصر
می دونم . ولی منظور من نحوه تعریف متغیر استاتیک است یعنی متغیری که با خارج شدن از یک تابع یا پروسیجر مقدار آن حفظ شود. همانطور که گفتم این کد در دلفی 5 اجرا می شود. به طور دقیق مشکل من این است که نمی دانم در دلفی 2009 چگونه باید متغیر استاتیک تعریف کنم. حال اگر کسی نحوه تعریف این نوع متغیر را در دلفی 2009 می داند کمک کند.

Mahmood_M
جمعه 20 شهریور 1388, 21:39 عصر
می دونم . ولی منظور من نحوه تعریف متغیر استاتیک است یعنی متغیری که با خارج شدن از یک تابع یا پروسیجر مقدار آن حفظ شود. همانطور که گفتم این کد در دلفی 5 اجرا می شود.
مطمئنید که این کد در دلفی 5 بدون مشکل اجرا میشه ؟!
مقدار دهی به یک عبارت ثابت غیرمنطقی هست و در دستور زبان دلفی هم نیست و این کد در هیچ کدوم از نسخه های دلفی هم اجرا نخواهد شد ، مگر اینکه قواعد زبان دلفی در نسخه های بعد از 5 تغییر کرده باشه ! ...


به طور دقیق مشکل من این است که نمی دانم در دلفی 2009 چگونه باید متغیر استاتیک تعریف کنم. حال اگر کسی نحوه تعریف این نوع متغیر را در دلفی 2009 می داند کمک کند.
...

یعنی متغیری که با خارج شدن از یک تابع یا پروسیجر مقدار آن حفظ شود.
اگه منظورتون اینه که مقدار متغیر بعد از انجام عملیات به مقدار اولیه برنگرده ، می تونید متغیر رو در قسمت Var اصلی Unit یا در قسمت Public فرم تعریف کنید ولی اگه منظورتون اینه که مقدارش همواره ثابت باشه ، اونوقت باید به عنوان یک ثابت ( Const ) تعریفش کنید ...

نکته اصلی مکان تعریف متغیر هست ، یا متغیر در خود تابع و یا Procedure تعریف میشه که در این صورت با هر بار فراخوانی تابع یا Procedure متغیر از نو مقدار دهی میشه ( یعنی به عنوان یک متغیر جدید در حافظه براش مکانی تعریف میشه ) ولی اگه متغیر در جایی خارج از تابعی خاص تعریف بشه ، مثل قسمت Public فرم ، با Create شدن فرم مکانی در حافظه به متغیر اختصاص داده میشه و تا نابودی کامل فرم هم مکانش در حافظه موجوده ...

موفق باشید ...

Ahmad Chehreghani
جمعه 20 شهریور 1388, 23:59 عصر
کد را به صورت زير تغيير بديد


const
{$J+}
bln : Boolean = false;
{$J-}
begin
bln := not bln;
if bln then
memo1.Hide
else
memo1.Show;
end;

vcldeveloper
شنبه 21 شهریور 1388, 01:07 صبح
ولی منظور من نحوه تعریف متغیر استاتیک است یعنی متغیری که با خارج شدن از یک تابع یا پروسیجر مقدار آن حفظ شود.
به این نمیگن متغیر استاتیک. استاتیک در برنامه نویسی شی گرا مفهوم خاص خودش را داره.

اونی که شما دنبالش هستید، اسمش هست Global Variable یا متغیر عمومی.


همانطور که گفتم این کد در دلفی 5 اجرا می شود. به طور دقیق مشکل من این است که نمی دانم در دلفی 2009 چگونه باید متغیر استاتیک تعریف کنم.
توی نسخه های قدیمی دلفی روی اینجور مسائل زیاد سخت گیری نمی شد، برای همین هم شما می تونستید یک ثابت (Const) را در کد تغییر بدید، در صورتی که این برخلاف تعریفی هست که از ثابت میشه. ثابت همانطور که از اسمش هم پیدا ست، نباید در کد قابل تغییر باشه، اگر قابل تغییر باشه، دیگه اسمش نمیشه Const، بلکه میشه Variable.

Hamid.Kad
شنبه 21 شهریور 1388, 14:48 عصر
جناب کشاورز جسارتاً عرض کنم فکر میکنم که اسم این متغیرها استاتیک است (http://delphi.about.com/od/beginners/a/typedconstant.htm) و یا به عبارت دیگر Constant Type. و بنظرم هنوز هم کاربرد دارند. بعضی وقتها که به هر دلیلی استفاده از متغیرهای عمومی به صلاح نیست (مثلاً برای مخفی سازی (با فرض اینکه از کلاس استفاده نمی کنیم)) این متغیرها جایگزین مناسبی هستند

vcldeveloper
شنبه 21 شهریور 1388, 17:20 عصر
فکر میکنم که اسم این متغیرها استاتیک است (http://delphi.about.com/od/beginners/a/typedconstant.htm) و یا به عبارت دیگر Constant Type.
اطلاق واژه متغیر برای این نوع داده درست نیست، چون متغیر یعنی چیزی که قابل تغییر باشد، در حالی که این نوع از داده قابل تغییر نیست.
استفاده از واژه Static هم درست نیست، هر چند از نظر معنایی با Constant قرابت داره، ولی چون نوع خاصی از داده در برنامه نویسی شی گرا وجود داره که به آن Static گفته میشه، مثل Static Property، کاربرد این واژه هم چندان مناسب نیست.


و بنظرم هنوز هم کاربرد دارند.
من هم جایی نگفتم که کاربرد ندارند. ولی کاربردشان این نیست که آنها را تعریف کنید، بعد مقدارشان را تغییر بدید، چون اصولا برای اینکه مقدارشان تغییر داده نشه بصورت Constant تعریف شدند. اگر قرار باشه مقدار داده ایی در کد تغییر داده بشه (مثل کاری که این کاربر میخواد انجام بده)، باید از Global Variable استفاده بشه.

Hamid.Kad
شنبه 21 شهریور 1388, 18:25 عصر
اطلاق واژه متغیر برای این نوع داده درست نیست، چون متغیر یعنی چیزی که قابل تغییر باشد، در حالی که این نوع از داده قابل تغییر نیست.
این نوع داده ها هم تغییر می کنند! شاید بهتر بود که می گفتید لفظ استاتیک چندان مناسب نیست که در این صورت با شما موافقم.

ولی چون نوع خاصی از داده در برنامه نویسی شی گرا وجود داره که به آن Static گفته میشه، مثل Static Property، کاربرد این واژه هم چندان مناسب نیست.
لغت استاتیک قبل از اینکه در زبانهایی مثل C++‎‎‎‎‎‎‎ وجود داشته باشه در C استاندارد موجود بوده. منظورم اینه که عقبه کلمه استاتیک اینجوری نبوده که مخصوص شیءگرایی بوده باشه و به اشتباه برای زبانهای قدیمی تر هم استفاده بشه.

اگر قرار باشه مقدار داده ایی در کد تغییر داده بشه (مثل کاری که این کاربر میخواد انجام بده)، باید از Global Variable استفاده بشه.
فرض کنید نیاز داشته باشیم که مقدار متغیری بعد از خروج از تابع نگهداری بشه. یک راه حل اینه که از متغیر عمومی استفاده بشه. حالا اگه نیاز به این باشه که توابع دیگه به این متغیر دسترسی نداشته باشند، چه روشی استفاده میشه؟ یک راه حل ساده و کارامد (البته بدون استفاده از کلاسها ) همین متغیرهای استاتیک هستند.

vcldeveloper
شنبه 21 شهریور 1388, 19:22 عصر
لغت استاتیک قبل از اینکه در زبانهایی مثل C++‎‎‎‎‎‎‎‎ وجود داشته باشه در C استاندارد موجود بوده. منظورم اینه که عقبه کلمه استاتیک اینجوری نبوده که مخصوص شیءگرایی بوده باشه و به اشتباه برای زبانهای قدیمی تر هم استفاده بشه.
بله موجود بوده، ولی الان پارادایم غالب در برنامه نویسی تغییر کرده، و الفاظ با توجه به آن معنی گزاری میشند.


این نوع داده ها هم تغییر می کنند! شاید بهتر بود که می گفتید لفظ استاتیک چندان مناسب نیست که در این صورت با شما موافقم.
شما می تونید از دلفی 7 تا دلفی 2010 سعی کنید تا مقدار یک Const را در کد تغییر بدید، و ببینید کامپایلر چه خطایی بهتون میده. البته می تونید با رهنمود کامپایلر $J+ کد را کامپایل کنید، اما می بینید که در راهنمای کامپایلر هم به شما توضیح داده شده که این رهنمود برای سازگاری با کدهای قدیمی دلفی وجود داره، و استفاده از آن توصیه نمیشه.

Hamid.Kad
شنبه 21 شهریور 1388, 20:37 عصر
دلفی 2010 رو راهنماش رو ندارم ولی راهنمای دلفی 7 چیزی که شما فرمودید رو ذکر نکرده و فقط گفته که بهتره که هنگام کامپایل، این دایرکتیو فعال نباشه. چون که به قول شما پارادایم برنامه نویسی تغییر کرده و منطقی هم بنظر نمیرسه که فعلاً طرحی برای حذف این نوع داده داشته باشند. چون اون مساله ساده ای که توی پاراگراف آخر پست 9 مطرح شد، بجز استفاده از این نوع داده روش دیگه ای نداره. حتی در صورت استفاده از کلاس و بخش private باز هم اون متغیر در خود همون یونیت قابل دسترسیه (بر خلاف C++‎) !

vcldeveloper
شنبه 21 شهریور 1388, 23:31 عصر
اون مساله ساده ای که توی پاراگراف آخر پست 9 مطرح شد، بجز استفاده از این نوع داده روش دیگه ای نداره.
برای اون مسئله شما حداقل 3 راه حل مختلف وجود داره، که یکی از آنها استفاده از اشیاء هست. اگر فرض بگیریم به هر دلیلی برنامه نویس نخواد از شی ها استفاده کنه، آنها را بسازه و آزاد کنه، راه دومش استفاده از static class هست که نیازی به Create و Free شدن نداشته باشه. اگر اصلا برنامه نویس با مفهوم کلاس مشکل داشته باشه، و حاضر نباشه از هر نوع کلاسی استفاده کنه، راه سوم این هست که اون تابع را در یک یونیت مجزا بنویسه، و متغیر عمومی را در بخش Implementation اون یونیت تعریف کنه، تا به جز اون تابع، توابع دیگه به اون متغیر دسترسی نداشته باشند، و از طرفی داده برای آن تابع قابل تغییر باشه.


حتی در صورت استفاده از کلاس و بخش private باز هم اون متغیر در خود همون یونیت قابل دسترسیه (بر خلاف C++‎‎) !
در ++C مفهومی به نام "کلاس دوست" وجود داره که میتونه به داده های خصوصی کلاس دیگه دسترسی داشته باشه. این مفهوم در دلفی برای کلاس های یک یونیت وجود داره. برنامه نویس هم مجبور نیست که چند کلاس را با هم در یک یونیت قرار بده.
به فرض هم اگر مجبور باشه که چند کلاس را با هم در یک یونیت قرار بده، میتونه داده ایی که مایل نیست سایر کلاس ها به آن دسترسی داشته باشند را بصورت strict private تعریف کنه. داده ایی که به صورت strict private تعریف بشند، توسط هیچ کلاسی، حتی کلاس های همون یونیت، قابل دسترس نیستند.


راهنمای دلفی 7 چیزی که شما فرمودید رو ذکر نکرده و فقط گفته که بهتره که هنگام کامپایل، این دایرکتیو فعال نباشه.
راهنمای دلفی 7 میگه:

but for new applications it is recommended that you use initialized variables and compile your code in the {$J-} state.

یعنی برای نرم افزارهای جدید توصیه می شود که از متغیرهای مقداردهی اولیه شده استفاده کنید، و این رهنمود را غیرفعال کنید. قبل از این هم توضیح میده که این رهنمود بطور پیش فرض غیرفعال هست، و اگر از کدهای قدیمی استفاده می کنید، آن را فعال کنید.

Hamid.Kad
یک شنبه 22 شهریور 1388, 09:20 صبح
دو مورد اولی که ذکر کردید بنده هم قبول دارم. و قبلاً هم ذکر کردم که فرض کنیم از مفهوم کلاس و شیءگرایی قرار نیست استفاده بشه. در مورد راه حلی که توی قسمت اول فرمودید (که در یک یونیت مجزا اون تابع رو تعریف کنیم) بنظرتون وقتی میشه از یک متغیر استاتیک استفاده کرد و کار رو راحت کرد ارزش داره این همه دردسر رو تحمل کنیم؟ حالا اگه 10 تابع همچین حالت رو داشتند چی؟ 10 تا یونیت تعریف میکنید؟ اگه 20 تا شدن چی ؟ (البته میدونم که توی این رنج دیگه برنامه نویس باید بره سراغ شیءگرایی :لبخندساده:) شاید هم این مورد رو در پاسخ به اینکه بنده عرض کردم راه دیگه ای نداره فرمودید که دیگه جای بحث نداره. در مورد سوم هنوز هم با نظر شما موافق نیستم که این نوع داده برای تطابق با ورژنهای قبلی وجود داره. چون برداشتی که من از این جمله میکنم این نیست که هشدار داده شده باشه که در ورژنهای بعدی حذف خواهد شد. فقط ذکر شده که اون نوع متغیرها بهتره که استفاده بشه. مثل اینکه توی کار با یه کامپوننتی مثل AdoTable میگه بهتره Active = true کنید تا اینکه open کنید. چون یه کم سرعتش بیشتره. حالا این دلیل نمیشه که نتیجه بگیریم توی طولانی مدت متد open قراره حذف بشه. خلاصه خیلی مخلصیم علی آقا....