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

کانکت سنتی را فراموش کنید ! استفاده از 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, 1 views today

Print Friendly
Facebook0Google+0Twitter0LinkedIn0

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

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

۱۸ نظر

  1. خیلی تووپ بود ، دم شما گرم !
    راستی یه جا لاندا گفتی یه جا 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

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

    • سلام.هستم! 🙂 اگه میتونی نظرت رو در مورد نحوه اجرا مسابقه تو بخش پیشنهاد و انتقاد مطرح کن تا با بقیه به یه طرح پخته برسیم.
      حکومتت با پروژه هات با اون ده درصد برنگشته همش تو حلقم 😛

  3. سلام

    ۱- تشکر

    ۲- یه مدت که سی شارپ خیلی به چشم و گوشم می خورد!، شروع کردم به تنهایی مطالعه کردن و بدون همراه دیگه ای. وارد نیستما، یه کلیاتی می دونم. اینو گفتم تا شماره ی ۳ رو بگم!

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

    ۴- یادمه در سی شارپ auto، همان var بود و  lambda هم که به کرات استفاده میشه و در linq هم کاربرد. ( در حقیقت lambda ، به نوعی خلاصه شدن نوشتن به طریق anonymous است.) دانستن این مطالب بود که باعث فهم آسان تر این مطلب شد.

    ۵- این مطلب رو به زبان ها و مثال های دیگر هم می توان اشاره نمود که فعلا می گذریم.

    ۶- در آینده (کی !!)، قصدم اینه که دوباره با کنکاش بیشتر ++C و Qt رو بررسی کنم. چند وقت پیش ها یه سینتکس هایی از ورژن جدید ++C دیدم که خیلی برایم جالب بود.

    ۷- آقا این فونت قابل تنظیمه یا من بلد نیستم . اینو گفتم تا بیننده ریز نبینه، وگرنه بنده مشکلی ندارم.

    ۸- این قابلیت های جدید بسیار عالی هستند و  جسارت نباشه و وقت داشتید از این مطالب بگذارید و جسارت نباشه بعد از امتحان فوق و انشاءالله قبل از رفتن برای فوق هر چی بلدید رو بگذارید که بعید می دونم دیگه وقت داشته باشید!!! من نبودما ، من محو شدما و من نیستما!!!

    ۸- باز هم بسیار تشکر 

    • به سلام علیرضا. من الان دارم با گوشی جواب کامنت میدم و نمیشه بند به بند جواب داد.ولی سعی میکنم همه رو شامل شه.
      درمورد سیشارپ: ای سی شارپ بلد به ماهم ببلدان:-)
      ولی درمورد امکانات جدید سی++ خودمم خیلی دوست دارم در موردش گفته بشه.حتما.البته اگه کسی تقبل کنه که عالیه.
      ممنون از نظرت ولی اون روزا دورقمی کامنت میذاشتی.هعی!

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

    ♥♥♥   c++   ♥♥♥

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

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

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

جوابی بنویسید

ایمیل شما نشر نخواهد شد.خانه های ضروری نشانه گذاری شده است. *

*


+ 4 = ده