کانکت سنتی را فراموش کنید ! استفاده از Lambda expressions در کانکت

سلام دوستان. یه خبر خوب!‌ شما می تونید از lambda expressions در connect کیوت استفاده کنید !

البته توی قسمت قبل در مورد سینتکس جدید کانکت شدن در کیوت ۵ صحبت کردیم. ولی این جلسه هیجانش بیشتره !( البته اگه حوصله دردسر ندارید بی خیال این قسمت بشید!)

خب بذارید اول خیلی مختصر بدونیم Lambda expression ها چی هستند؟!

یکی از مهمترین اجزا برنامه نویسی سی توابع هستند اما :

اصلا ما تابع می نویسیم برای چی؟!

علی شما جواب بده !

توابع برای این نوشته میشند که یه کد تکراری بارها استفاده بشه. ولی خیلی وقتا توابعی که میسازیم خیلی قابل استفاده مجدد نیستند . اصلا ارزش نداره بهشون بگیم تابع یا اصلا کدمون رو طولانی کنیم تا اینکه یه تابع بنویسیم که فقط یک بار ( یا حتی چند بار ولی فقط توسط یک قسمت از برنامه ) استفاده میشه. مثلا فرض کنید میخواید یه QTimer داشته باشید که هر بار که ۱۰۰۰ میلی ثانیه گذشت یک واحد به متغیر _x  اضافه کنه. آیا اساسا(دکتر افشار!)‌ نوشتن یک تابع یه خطی که فقط وظیفه اش اضافه کردن یه واحد به یک متغیر است دلیل منطقی داره ؟!

Lambda در واقع یک تابع بی نام هستش که جاهایی ازش استفاده میکنیم که ارزشی نداره یه تابع جداگانه (با نام )‌ برای اون کار بنویسیم!

خب بهتره کم کم بریم سراغ اینکه چطور یه عبارت لاندا بنویسیم (گیر نده آقا به این اسم خسته شدم از بس نوشتم lambda expressions ! )  ساده ترین لاندا به صورت زیره:

این عبارت از سه قسمت اصلی تشکیل شده است :‌

[] کپچر لیست Capture List 

( ) لیست آرگومان ها (پارامتر ها )  

{ }  هم که بدنه تابع بی نام (لاندا) رو داخلش داره.

Capture List

در واقع مشخص میکنه که چه چیزی از خارج محدوده  {  } عبارت لاندا و به چه صورتی در داخل محدوده  {  } در دسترس باشه. مثلا اگه یه متغیری بیرون عبارت لاندا تعریف شده آیا اساسا(دکتر افشار!)‌در داخل عبارت لاندا در دسترس باشه یا نه و ثانیا این دسترسی به چه صورتی باشه. کپچر لیست رو میشه به صورت های زیر مشخص کرد:

  1. یک مقدار: [x] (فقط ایکس قابل خواندن است )
  2. یک رفرنس [&x] (ایکس هم قابل خواندن و هم قابل تغییر است )
  3. تمام متغیر های موجود در محدوده فعلی به صورت رفرنس [&]
  4. مثل مورد چهار فقط با این تفاوت که متغیر ها رفرنس نیستند و فقط مقادیرشان موجود است. [=]

خیلی گیج کننده است ؟!‌به مثال های زیر توجه کنید.

اولا توی کریتور یه پروژه Plain C++ Project بسازید از قسمت Non-Qt Project و در ضمن در فایل .pro خط زیر رو اضافه کنید. (‌حتما حتما نیاز به کیوت ۵ دارید )

خطوط زیر رو یه جایی مثلا توی main تون اضافه کنید.

خط اول که یه متغیر خیلی ساده تعریف کردم. خط دوم هیجان اتفاق می افته ! شما یه متغیر به نام f تعریف کردید ولی تایپش رو گذاشتید auto  . این کلمه کلیدی جایی کاربرد داره که خود کامپایلر میتونه تشخیص بده تایپ یه متغیر چیه. مثلا حتی خط اول رو میتونید به صورت زیر بنویسید:

ای کاش یه مرد پیدا میشد یکم از ویژگی های C++11 واسمون میگفت.هعی !

توی خط دوم ما یه عبارت لاندا تعریف کردیم. عبارتی که اگه صدا زده بشه ( در خط سه )‌فقط تنها کاری که میکنه اینه که یه salam چاپ میکنه (‌تا اینجا اساسا(دکتر افشار!‌ بابا ولمون کن ) هیچ فرقی بین لاندا و اشاره گر به تابع نبود . ادامه آموزش تفاوت ها رو روشن میکنه)

خب حالا اگه بخوایم متغیر x رو هم توی عبارت لاندامون چاپ کنیم چکار کنیم . بذارید خط زیر رو امتحان کنیم :

خطای زیر منتظر شماست !

/home/saeed/iprogrammer/sources/Cpp11/main.cpp:8: error: ‘x’ is not captured auto f = [](){cout << “salam”<<x;}; ^

خب باید چیکار کنیم؟ متغیر x که باید در دسترس باشه؟! باید در کپچر لیست بگیم به کیا و چطوری میخوایم دسترسی داشته باشیم:

الان دیگه مشکلی نیست و مقدار x هم چاپ میشه.

حالا امتحان زیر رو امتحان کنید !؟‌:

یعنی سعی کنید مقدار x رو در داخل لاندا تغییر بدید. نمیشه ! خطای زیر !

/home/saeed/iprogrammer/sources/Cpp11/main.cpp:8: error: increment of read-only variable ‘x’ auto f = [x](){cout << “salam”<<x++;}; ^

خب اگه بخوایم تغییر بدیم چیکار کنیم پس؟ کافیه در کپچر لیست بگید که آقا متغیر x رو به صورت رفرنس بفرست بیاد! در این صورت تغییر پذیر خواهد بود: امتحان کنید :

الان دیگه چون کپچر لیست رو به روز کردیم مقدارx قابل تغییر هستش و اون cout دوم مقدار ۱۱ رو چاپ میکنه که درسته.

نکته ای که هست میشه به کپچر لیست بیش از یه متغیر رو با نوع های متخلف مشخص کرد و فرستاد :

الان x قابل تغییر ولی y غیر قابل تغییر.

میشه بگید که تمام متغیر های در اون محدوده (‌بلاک) به صورت رفرنس در عبارت لاندا در دسترس باشند :

و میشه گفت همه By Value نه By Reference :

الان حتما کد بالا خطا خواهد داد که x,y قابل تغییر نیستند.

البته لاندا چیزای دیگه هم داره که موضوع بحث ما فعلا نیست.

خب این همه روضه تو محرم خوندیم که چی بگیم؟

استفاده از Lambda Expressions در کیوت

خیلی وقتا دیدید که توی connect اونقدر کار کوچیک هستش که اصن آدم اصابش خورد میشه بخواد یه اسلات بنویسه و خودش رو اینقدر اذیت کنه. مثلا فرض کنید یه QTimer دارید که میخواید هر یه ثانیه به یه ثانیه مقدار یه QLabel رو یکی زیاد کنه. راه حل عادیش رو یکم روش فک کنید!‌نه مردونه فکر کنید!‌‌(‌مث نظر سنجی نباشه که … )

خب حالا راه حل Qt فایویش ! و C++11 ایش !

نه اسلاتی نه چیزی !‌ وژدانا ! کدوماش خشگل تر و تمیز تره؟!

مهم ترین خط این خط هستش :

خب در مورد نحوه کانکت کردن با اشاره گر به اعضای کلاس ها بدون استفاده از عبارت SIGNAL قبلا صحبت کردیم. فقط اینجا به جای اسلاتی که باید اجرا بشه یه عبارت لاندا قرار داره که تفسیرش دیگه خیلی راحته . & به این خاطره که ما به x و lbl به صورت رفرنس (‌قابل تغییر نیاز مند هستیم )‌البته شاید قشنگ تر بود اگه به این صورت می نوشتیمش :

چون فقط به x , lbl نیاز داریم.

امید وارم از این آموزش بهره وافی ! رو برده باشید. البته شاید لازم باشه کانترخودتون! رو صفر کنید و دوباره از سر اول مطلب رو بخونیدش تا متوجه بشید. طبیعیه خودتون رو نگران نکنید!

۸,۱۷۵ total views, 8 views today

Print Friendly, PDF & Email

درباره ی سعید دادخواه

یه برنامه نویس !

همچنین ببینید

اجرای تنها یک نمونه از برنامه (Single Instance)

درود. چند روز پیش در بخش سوال و جواب یکی از دوستان به نام tmtt …

18
دیدگاه بگذارید

avatar
9 Comment threads
9 Thread replies
0 دنبال کنندگان
 
Most reacted comment
داغ ترین نخ نظرات
9 کامنت گذاران
dr.b4neaidinعلی ناصری میل کاریزsoft20سید امیر کامنت گذاران اخیر
  مشترک شو!  
جدیدترین قدیمی‌ترین دارای بیشترین امتیاز
میخوام باخبر شم از
مجتبی
Guest

خیلی تووپ بود ، دم شما گرم !
راستی یه جا لاندا گفتی یه جا Lumda 🙂
فک کنم اینجا مث وبلاگ من غلط نگارش مستحب موکده http://qtips.ir/wp-content/plugins/wp-monalisa/icons/wpml_bye.gif دوستش دارم http://qtips.ir/wp-content/plugins/wp-monalisa/icons/wpml_heart.gif

علیرضا
Guest
علیرضا

من برگشتم تا بر وبلاگ حکومت کنم و همه شمارو برده خود کنم(ها ها ها….)
سیستمم تقریبا درست شد و حدود ۹۰% اطلاعاتم برگشت(به جز مهماش)حالا کیوت رو هم گذاشتم توی دانلود بیخیال اینکه تممام پروژه هام هم رفتن
بگذریم.راجب مسابقه رمز گشایی نظرت چیه؟هستی طراحیش کنیم(یا کنی:D)یکی دیگه اینکه اگه یه آموزش در باره اینکه چطور سورسمون رو کدینگ کنیم تا لو نره بذاری ممنون میشمhttp://qtips.ir/wp-content/plugins/wp-monalisa/icons/wpml_heart.gif
دیگه چیز دیگه ای به ذهنم نمیرسه تازه از ریکاوری برگشتم خستم برم یکم استراحت کنم
((حتما نظرتو در باره مسابقه رمزگشایی بگو))

14alireza
ویرایشگر
14alireza

سلام ۱- تشکر ۲- یه مدت که سی شارپ خیلی به چشم و گوشم می خورد!، شروع کردم به تنهایی مطالعه کردن و بدون همراه دیگه ای. وارد نیستما، یه کلیاتی می دونم. اینو گفتم تا شماره ی ۳ رو بگم! ۳- الحمدلله با یکبار مطالعه، این مطلب رو فهمیدم. نخواستم از خودم تعریف کنم، حداقل وقتی آدم این طراحان رو می بینه، مجالی برای ابراز دانش نمی مونه. خواستم بگم بر این نظر هستم (در پستی که در مورد نظرات برنامه نویسان هم نوشته بودید، اشاره کرده بودند)، آشنایی با برنامه های دیگر، سینتکس ها و ایده هایشان، بسیار… Read more »

علیرضا
Guest
علیرضا

راستش اول متنو نخوندم و نظر دادم 😀
بابا این c++11 چیه؟؟؟c# و کلا دات نت باید برن پشمک بفروشن(که متاسفانه برعکسش اتفاق افتاده)
عاشق c++ ام.یعنی عاشقشم.عاشق کیوتی ام و عاشق این وبلاگ

♥♥♥   c++   ♥♥♥

سید امیر
Guest
سید امیر

خیلی عالی بید، دقیقا مثل توابع بی نام در جاوا اسکریپت هست
function(){}
 

soft20
Guest

         http://qtips.ir/wp-content/plugins/wp-monalisa/icons/wpml_bigsmile.gif

علی ناصری میل کاریز
Guest

آقا عالی بود واقعا مرسی این آموزش فوق العاده کاربردیه ۲۰http://qtips.ir/wp-content/plugins/wp-monalisa/icons/wpml_rose.gif

aidinMC
Member
aidinMC

حال کردم…
ایول.

dr.b4ne
Member
dr.b4ne

عالیییی . حرف نداره . مرسی … کدهام آب رفت …