پرچمداران
-
در همه بخش ها
- همه بخش ها
- فایل
- دیدگاه فایل
- نقد و بررسی فایل
- مقالات
- مقاله دیدگاه
- مقاله نقد و بررسی
- صفحات استاتیک
- صفحه دیدگاه
- صفحه نقد و بررسی
- کتابخانهها
- کتابخانه دیدگاه
- کتابخانه نقد و بررسی
- رویداد
- دیدگاه های رویداد
- بازبینی رویدادها
- تصاویر
- دیدگاه های تصویر
- نقد های تصویر
- آلبوم ها
- نظر های آلبوم
- نقد های آلبوم
- پست ها
- نوشتههای وبلاگ
- دیدگاه های وبلاگ
- بروزرسانی وضعیت
- پاسخ های دیدگاه ها
-
تاریخ سفارشی
-
همه زمان ها
4 خرداد 1397 - 10 فروردین 1403
-
سال
9 فروردین 1402 - 10 فروردین 1403
-
ماه
10 اسفند 1402 - 10 فروردین 1403
-
هفته
3 فروردین 1403 - 10 فروردین 1403
-
امروز
10 فروردین 1403
-
تاریخ سفارشی
پنجشنبه, 6 خرداد 1400
-
همه زمان ها
مطالب محبوب
در حال نمایش مطالب دارای بیشترین امتیاز از زمان پنجشنبه, 6 خرداد 1400 در همه بخش ها
-
3 امتیازاصطلاحاتی که بهتر است در مورد C++ مدرن بدانید! داشتم به این فکر میکردم که برخی از مبتدیان برنامهنویسی به خصوص کسانی که به سراغ زبانهایی مثل سی++ میروند معمولاً مستقیم وارد کد نویسی میشوند و به این گمان که آغاز برنامهنویسی یعنی نوشتن یک کد با خروجی «سلام، دنیا»! دریغ از آن که بعضی از موارد مانند «معرفی کامپایلر و انواع آن» و حتی «ساختار برنامههای نوشته شده تحت سیپلاسپلاس» و یا حتی «مدیریت حافظه» را در نظر بگیرند! من معمولاً در مقالات و آموزشهای خودم به این اشاره میکنم که قبل از هر چیز باید با ساختار برنامههای نوشته شدهٔ یک زبان آشنا شد و سپس به بررسی موارد دیگر مانند نحو زبان و یا دیگر ویژگیهای آن. بنابراین، یکی از خطرناکترین عواملی که موجب خونریزی داخلی یک نرمافزار در برنامههای نوشته شده توسط برنامهنویس درC++ میشود عدم مدیریت حافظهٔ اختصاص یافته است که باید بعد از اختصاص یافتن حافظه در زمان معین آن را آزادسازی کند. در صورتی که این کار صورت نگیرد عمل Memory Leak (نَشتِ حافظه) رخ داده است. بسیاری از علاقهمندان بر این باورند که چون سی++ دارای GC یا همان Garbage Collector (زبالهروب) نیست که البته صحیح است! سی++ دارای GC نیست و این امر محدودیت یا نکته ضعف آن هم نیست! سی++ همه چیز را آزادانه در اختیار برنامهنویس قرار میدهد تا خود در زمان مناسب روش مدیریت حافظه را انتخاب کند. در علوم رایانه بازیافت حافظه یا زبالهروبی نوعی مدیریت حافظهٔ خودکار است که عمل مدیریت حافظههای اختصاص یافته شده را به دست میگیرد و اکثر زبانهای برنامهنویسی مانند #C، جاوا و دیگر موارد مشابه به آن مجهز به این ویژگی هستند که البته وجود چنین ابزارهایی میتواند توهمی را ایجاد کند مبنی بر آن که دیگر نیازی به مدیریت منابع نیست، اما در بعضی موارد مدیریت منابع هنوز یک الزام است چرا که منابع آزاد شده هنوز هم دلیل بر نشتِ حافظه هستند. این نشت حافظه زمانی اتفاق میافتد که اشیاء هنوز قابل دسترس از طرف اشیاءای که زنده هستند اما هرگز مورد استفادهٔ دوباره قرار نمیگیرند اتفاق بیافتد. در بسیاری از زبانهای برنامهنویسی این ویژگی وجود دارد که طبیعتاً مدیریت توسط GC راه حل بسیار خوب و بی نقصی نیست. اما با توجه به عدم وجود GC در سی++ اکثراً با روشهای دستی برای مدیریت حافظه میپردازند که رایجترین روش آن استفاده از عمل new و delete در اختصاص دادن و آزادسازی حافظه است. بسیاری از ما با سی++ در دانشگاه و یا دروس مرتبط با مفاهیم اولیه برنامهنویسی آشنا شده ایم، اما معمولاً مفاهیم مربوطه برای نسلهای قبلی و منسوخ شدهٔ این زبان است. بهتر است در نظر داشته باشید که برنامهنویسی مدرن یعنی پیروی از اصول و قوانین جدیدی که در تکامل یافتن یک زبان به کار گرفته میشود. RAII : Resource Acquisition is initialization بنابراین، باید در نظر گرفت مدیریت حافظه از استاندارد ۱۱ به بعد این زبان به روشهای بسیار مدرنتری هوشمند سازی شده است. یکی از بهترین تکنیکهای موجود در هستهٔ زبان اصطلاح Raiiاست. الگوی RAII مخفف «Resource Acquisition is initialization» که به عنوان یک اصطلاح در برنامهنویسی مطرح میشود به صورت یک تکنیک (کنترل تخصیص منابع و آزادسازی آنها) یکی از ویژگیهای اصلی در سیپلاسپلاس است. با قرار دادن چنین کدی دیگر نیاز به فراخوانی آن کد توسط برنامهنویس در مخرب (ویرانگر) نیست و کامپایلر خود این کار را انجام میدهد. به طور کلی این الگو هر شیء را مجبور میسازد تا در زمان مواجه با رفتارهای ناهنجار خود را پاکسازی کند. به طور کلی هنگامی که شما یک شیء را مقداردهی اولیه میکنید، قبل از انجام آن باید منابع مورد نیاز آن را تأمین کنید (در سازنده). هنگامی که یک شیء از محدوده خارج میشود، هر منبعی را که مورد استفاده قرار داده است باید آزاد کند (در مخرب - ویرانگر). نکات کلیدی هرگز نباید یک شیء به حالت نیمه آماده یا نیمه از بین رفته وجود داشته باشد! وقتی که یک شیء ساخته میشود، آن شیء باید در حالت آماده باش برای استفاده باشد. وقتی یک شیء از محدوده خارج میشود، باید منابع اختصاص یافتهٔ خود را در حافظه آزاد کند (کاربر مجبور به انجام کار دیگری نیست). آیا RAII عنوان بدی برای مفهوم این تکنیک است! از نظر خالق سیپلاسپلاس نام بهتر میتواند به صورت زیر باشد: مدیریت منابع مبتنی بر حوزه (محدوده یا دامنه) : Scope Based Resource Management چیزی که تکنیک RAII را نقض میکند چیست؟ اشارهگرهای خام و تخصیص حافظه فراخوانی با کلمهٔ کلیدی new برای دست آوردن یا اختصاص دادن منبع (حافظه). فراخوانی با کلمهٔ کلیدی delete برای آزادسازی منبع (حافظه). اما این مورد به صورت خودکار بعد از خروج از محدوده توسط اشارهگرها صورت نمیگیرد. void rawPtrFn() { // acquire memory resourceNode* n = newNode; // manually release memory delete n; } بنابراین در صورتی که برنامهنویس استفاده از کلمهٔ کلیدی delete را برای آزادسازی حافظه فراموش کند (نشتِ حافظه) رخ میدهد. این عمل کافی است تا تکنیک RAII را نقض کنیم. void UseRawPointer() { // Using a raw pointer -- not recommended. Song* pSong = new Song(L"Nothing on You", L"Kambiz Asadzadeh"); // Use pSong... // Don't forget to delete! delete pSong; } بنابراین، راه حل RAII برای این امر در چیست؟ کلاسی داشته باشید که : حافظه را هنگام مقداردهی اولیه تخصیص دهد. حافظه را هنگام فراخوانی مخرب (ویرانگر) آزاد کند. دسترسی به اشارهگرهای زیرین را امکانپذیر کند. اشارهگرهای هوشمند (Smart Pointers) یک اشارهگر هوشمند یک شیء به سبکِ RAII است که تضمین میکند یک اشارهگر در هر زمانی که مناسب باشد حافظهٔ اختصاص یافته شده را آزاد میکند. به عنوان یک قاعده، برنامههای نوشته شده در سیپلاسپلاس مدرن (پیشرفته) هرگز نباید از اشارهگرهای خام (Raw) برای مدیریت حافظهٔ پویا (مشترک) استفاده کنند. برنابراین، در برنامههای مدرن سی++ به ندرت باید از کلمهٔ کلیدی delete جهت آزادسازی حافظه استفاده کرد. در واقع انجام این روش موجب جلوگیری از نشت حافظه است. این ویژگی اساساً مدیریت حافظهٔ خودکار را ارائه میدهد. زمانی که یک اشارهگر هوشمند دیگر استفاده نمیشود (زمانی که از محدودهٔ خود خارج میشود) حافظهٔ مورد نظر خود را به طور خودکار آزاد میکند.توجه داشته باشید که اشارهگرهای سنتی با عنوان اشارهگرهای خام (Raw Pointer) شناخته میشوند. اشارهگرهای هوشمند را میتواند یک شکل کلی از GC در نظر گرفت؛ نوعی مدیریت خودکار وقتی که دیگر توسط برنامه مورد استفاده قرار نمیگیرند حافظهٔ اختصاص یافتهٔ آن شیء به طور خودکار حذف میشود. در استاندارد ۱۱ سیپلاسپلاس سه نوع اشارهگر هوشمند معرفی شده است که همهٔ آنها در فایل سرآیند <memory> از کتابخانهٔ استاندارد STL معرفی شدهاند. کلاس std::unique_ptr یک اشارهگر هوشمند که دارای یک منبع تخصیص حافظهٔ پویا است. این شیء دارای یک اشارهگر به حافظهٔ پشته است، بنابراین نمیتوان آن را کپی کرد. تنها میتوان آن را جابجا (move) و مبادله کرد. خارج از این بیشتر مانند یک اشارهگر عادی رفتار میکند. { std::unique_ptr<Person> person(new Person("Kambiz")); if (person != nullptr) person->SetLastName("Asadzadeh"); if (person) DoSomethingWith(*person); } اگر دقت کنید، اپراتورهای -> و * اطمینان میدهد که unique_ptr میتواند اکثر اوقات شبیه به یک اشارهگر خام (Raw Pointer) استفاده شود. کاربردهای معمول از unique_ptr که باعث میشود از آن را به یک ابزار واقعی و ضروری تبدیل کند به صورت زیر است: آنها را میتوان با خیال راحت در داخل یک ظرف (Container) ذخیره کرد. هنگامی که به عنوان متغیرهای عضو کلاس دیگر استفاده میشوند، نیاز به حذف صریح در مخرب را از بین میبرند. در واقع نیازی نیست در مخرب کلاس خود شیءای را که حافظهای را به خود اختصاص داده است به صورت دستی آزاد کنید. علاوه بر این، موجب جلوگیری تولید خطاهای احتمالی از طرف کپی عضوها برای اشیاءای که باید حافظهٔ پویا داشته باشد در کامپایلر نیز میشود. آنها امنترین و توصیه شدهترین روشهایی برای انتقال مالکیت انحصاری، یا بازگشت به یک unique_ptr از یک تابع که شیء ای را در پشته ساخته است و یا با انتقال یکی از آنها به عنوان آرگومانی که در تابع میتواند به عنوان مالکیت بیشتر پذیرفته شود. در هر دو مورد، std::move به طور کلی باید مورد استفاده قرار بگیرد، و این انتقال مالکیت را به صورت صریح بیان میکند. انتقال مالکیت از قبل تعیین شده از طرف توابع امضاء شده معلوم میشود. از نشت حافطه جلوگیری میکند. همچنین، یک شیء unique_ptr میتواند حافظهٔ اختصاص داده شده را با استفاده از new[] مدیریت کند: { std::unique_ptr<int[]> array(new int[123]); DoSomethingWith(array.get()); } به طور معمول توصیه میشود که برای ساخت یک unique_ptr از std::make_unique() استفاده شود. کلاس std::shared_ptr شامل یک اشارهگری است که دارای یک منبع تخصیص حافظهٔ پویا با تفاوت اینکه میتواند چندین شیء را به صورت اشتراکی از یک منبع مشترک ردیابی کند. در واقع هنگامی که موجودیتهای متعددی همان شیء اختصاص یافته شده به حافظه را به اشتراک میگذارند، البته این وضعیت همیشه مشهود نبوده و یا ممکن است آن را به یک مالک واحدی اتخصاص دهید. این اشاره گر های هوشمند، شمارندهای از یک رشتهٔ ایمن(thread-safe) برای منبع حافظهٔ مشترک حفظ میکند و در زمانی که تعداد مرجع آن به صفر رسید، حذف میشود. در واقع این زمانی رخ میدهد که آخرین شیء مشترک از آن حذف شود. تابع use_count() نیز تعداد مراجع را بر میگرداند. همچنین مشابه unique_ptr این شیء یعنی shared_ptr میتواند آرایههای پویا را مدیریت کند که این ویژگی از استاندارد ۱۷ به بعد ممکن شده است. چندین شیء از shared_ptr ممکن است دارای همان شیء باشند. اگر یکی از موارد زیر اتفاق بیفتد، شیء از بین رفته و حافظهٔ آن آزاد میشود: آخرین بازمانده از شیء shared_ptr از بین رفته باشد. آخرین بازماندهٔ شیٔ shared_ptr که دارای یک اشارهگر از طریق اپراتور = و یا reset() است تعیین میشود. آنچه که shared_ptr را از unique_ptr متمایز میکند آن است که آنها میتوانند کپی شوند: { auto age = std::make_shared<int>(30); auto aliasAge = age; age.reset(); } کلاسstd::weak_ptr مانند std::shared_ptr است اما با تفاوت آن که شمارندهٔ آن افزایش نمییابد و اختیار شیء را به دست نمیگیرد. درواقع، بعضی اوقات نیاز است هنگام ساخت مخازنی از اشیاءای که به اشتراک گذاشته شدهاند بدانید آن شیء وجود دارد یا خیر. کاربرد آن نیز همراه با shared_ptr معتبر است و اطلاعاتی در بارهٔ اشیائی که توسط shared_ptr به دست گرفته است ارائه میکند. چند مثال در بارهٔ اشارهگرهای هوشمند: { std::unique_ptr<int> p(new int); // شیء p قابل استفاده در داخل حوزه است. } // در این بخش که خارج از دامنهٔ اشارهگر است حافظهٔ اختصاص یافته آزاد میشود. همانطور که مشخص است یک شیء که تحت اشارهگر هوشمند مورد استفاده قرار میگیرد تا زمانی که خارج از حوزهٔ خود قرار نگیرد قابل استفاده خواهد بود. نمونه کد پایین مثالی از نحوهٔ نمونه سازی تحت اشارهگرهای هوشمند است. void UseSmartPointer() { // Declare a smart pointer on stack and pass it the raw pointer. unique_ptr<Song> song2(new Song(L"Nothing on You", L"Kambiz Asadzadeh")); // Use song2... wstring s = song2->duration_; //... } // song2 is deleted automatically here.
-
3 امتیازبا سلام، با توجه به سوالات مکرر برخی از کاربران و خصوصاً دانشجویان جدید، تصمیم گرفته شد تا توضیحاتی دربارهٔ نحوهٔ یادگیری برنامهنویسی با سیپلاسپلاس بیان شود. قبل از هر چیز لازم است بدانید، سیپلاسپلاس یک زبان برنامهنویسی کاملاً تخصصی مهندسی است. بنابراین یادگیری آن طبیعتاً نیاز به تلاش، تحمل و پشتکار کافی در مقابل چالشهای آن خواهد داشت. مقدمه در حال حاضر بیش از سه دهه است که از ساخت و معرفی زبان برنامهنویسی ++C میگذرد. در رابطه با آن که هدف از ایجاد این زبان چه چیزی بوده و مزایای آن نسبت به زبانهای دیگر چه چیزی است (چرا موتور مخفی جهان مدرن امروزی است) را میتوانید در این مقاله مطالعه کنید. اما بسیاری از افراد علاقهمند به زبانهای برنامهنویسی تمایل بسیاری دارند تا در برنامهنویسی با این زبان به درجه مطلوب و درواقع (حرفهای) برسند. قبل از هر چیز باید مواردی را در نظر داشته باشیم که یاد گیری زبانهای برنامهنویسی به خودی خود کافی نیست! مخصوصاً زبانهای C و ++C مستلزم پیشنیازهای تخصصی بسیاری هستند که در روند تولید، توسعه، تجزیه و تحلیل لایههای مختلف مهم است. آیا زبان سیپلاسپلاس در حال توسعه است؟ به جرأت میتوانم بگویم که سیپلاسپلاس به عنوان پیشتاز زبانهای برنامهنویسی با سرعت بسیار زیادی در حال گسترش و توسعهٔ خود است. بهتر است بدانید این زبان از شیوهٔ نسخهنگاری معمولی بهره نمیبرند، بلکه از «استاندارد» (ISO/IEC) که کمیتهٔ استانداردسازی آن را تأیید و نهایی میکند بهره میبرد. بنابراین، بر اساس استانداردی پیش میرود که پیشنویسهها و بهبودهای آن تماماً با حفظ (پشتیبانی از عقبگرد) قابل توجه است. همانطور که در تصویر مربوطه میبینید، سیپلاسپلاس در آخرین بهروز رسانی، به نقشهٔ توسعهٔ خود در سالهای بعد نیز اشاره کرده است که در قالب استانداردهای ۲۳، ۲۶ و ۲۹ از الآن یاد شدهاند. چیزی که در هیچ زبانی در وضعیت فعلی به صورت نقشهٔ راه از توسعه آنها نمیتوان دید! این خود یک نکتهٔ بسیار مثبت است که تیم (کمیته) استانداردسازی این زبان کاملاً این اطمینان را میدهد که این زبان نسبت به نیاز و آینده در حال به روز بوده، است و خواهد بود. لازم است بدانید، استانداردهای فعلی، ۱۷ و ۲۰ و بعد ۲۳ به عنوان یک نسل انقلابی و جهش یافته از سیپلاسپلاس یاد میشوند، اگر شما تجربهٔ نوینی از برنامهنویسی را میطلبید، بهتر است به استاندارد ۲۰ خوشآمدگویی کنید که در کنار کارآیی بسیار عالی، یک نحو و سبک بسیار ساده و روان در اختیار توسعهدهنده قرار میدهد. در ادامه ما به سوالاتی که معمولاً توسط تازهکاران پرسیده شده است پاسخ دادهایم: ابعاد علمی و اقتصادی کار با ++C در ایران متاسفانه اکثر ما ملتی هستیم، تَنبَل و حاضر برای لُقمهٔ آماده! بنابراین بازار کار در ایران به گونهای است که بیشتر شرکتها و افراد توسعه دهنده به سراغ زبانهای سادهتر و در دسترستر (بی دردسر) میروند. غافل از آن که یک برنامهٔ تولید شده توسط سی++ بسیار سریع، جذاب، قدرتمند و انعطافپذیرتر است. همهٔ بحث در اینجا تمام نمیشود، چرا که شاید در سالهای اخیر وضعیت تقریباً فرق کرده و به کمک اطلاع رسانیهای اساتید و دوستان حرفهای، ما در این زمینه این اطلاعرسانی به خوبی صورت گرفته و توسعه دهندهها از قابلیتها پنهان این زبان آگاه شدهاند و میدانند که سیپلاسپلاس به عنوان یک زبان بسیار کاربردی در زمینههای مختلف جایگاه ویژهای دارد. شرکتها و گروههای برنامهنویسی بسیاری به دنبال برنامهنویسهای سی++ هستند که این امر نشان دهندهٔ این است که نسبت به سالهای گذشته پیشرفت و آگاهی جامعهٔ برنامهنویسی در این حوزه منطقیتر و بهتر شده است. من بارها در مورد بحث محدودیتهای سختافزاری، مشکلات و محدودیتهای پیش و روی قانون مور، مسائل مربوط به انرژی سبز و غیره صحبت کردهام. و اکنون زمان آن رسیده است که بیشتر در این باره فکر کنید که واقعاً چه ابزارهایی آیندهٔ بهتر و موثرتری در پیشرفت صنایع خواهند داشت. بنابراین، بهتر است قبل از هرچیز در نظر داشته باشید که هدف از این تاپیک، این نیست که اثبات کنیم یک زبان نسبت به زبان دیگر برتری دارد. هدف اصلی من این است به واقعیتهایی اشاره کنم که غیر منطقی نیستند. چرا که واقعاً کارفرمایانی وجود دارند که نیازمند به برنامهنویسانی هستند که تخصص خوبی در زبانهای برنامهنویسی دیگری مانند ++C دارند. همه چیز در زبانهای سطحبالاتر خلاصه نشده است! توجه داشته باشید که هدف از این توضیحات چنین نیست که بعد از خواندن این مطالب زبان برنامهنویسی مورد علاقهٔ خود را کنار گذاشته و به سمت سی++ بروید، خیر! یا مقصود آن نیست که با دیدن و شنیدن پیچ و خمهای آن از یادگیری آن منصرف شوید. من بارها گفتهام، تمامی زبانها به عنوان ابزارهای کاری شما در یک جعبهٔ ابزار هستند و هر زبانی حوزهٔ کاربردی خودش را دارد. بنابراین قبل از اینکه شما تصمیم بگیرید که چه زبانی را یاد خواهید گرفت باید حوزهٔ کاری وعلاقهٔ خودتان را مشخص کنید سپس وارد تحقیق و بحث و نظر خواهی راجع به آن زبان نمایید. مقایسهٔ زبان طبق این قانون کاملاً کار اشتباه و بچهگانه است و به هیچ عنوان در مورد یک زبان برنامهنویسی گاردِ تعصبی نگیرید. متاسفانه به خاطر تفکرات اشتباه و معرفیهای غیر منطقی و غیرعلمی برنامهنویسان کشور ما که ممکن است حتی خودِ شما هم چنین تصور کنید، در رابطه با سایر زبانها مانند سی++ بسیاری از کارفرمایان نیازمند چنین برنامهنویسانی هستند که در کشور ما واقعاً نیاز است. توجه داشته باشید که انتخاب درست این نیست که چون همه سراغ زبانهای پر مخاطبتری میروند و چون تمامی آگهیها استخدامی مرتبط با آنها است پس فقط باید آنها را یاد گرفت! خیر چنین تفکری اشتباه است و ضربهٔ بسیار بزرگی در صنعت و دانش آیندهٔ جامعهٔ تخصصی هر کشوری که به این شکل پیش میرود خواهد زد، چرا که ما باید طبق مسیر و سرعتی که دنیا در حال جهش است، خود را هماهنگ و بهروز کنیم. نکاتی در این میان وجود دارد که باید به آنها اشاره کرد: متاسفانه در کشور ما بسیاری از برنامهنویسان چه مبتدی چه حرفهای اینطور تصور میکنند که تولید محصول نرمافزاری یعنی برنامهنویسی یک نرمافزار که قرار است به بانک اطلاعاتی متصل شده و کارهایی مانند ثبت و ویرایش اطلاعات و در نهایت گزارش گیری و دیگر عملیات ممکن را انجام دهد! این تفکر به شدت اشتباه است! الآن دیگر سیستم نرمافزاری، معماریها و سبک و سیاقهای ساختوساز فرق کرده است. مبتنی بودن بر خدمات متمرکز، غیرمتمرکز و دیگر فناوریها بسیار مهم است. توجه کنید که بزرگترین و معروفترین فناوریها مطرح جهانی معمولاً به واسطهٔ این زبان طراحی میشوند، مانند، سیستمعاملها، نرمافزارها، زیرساختها و حتی بلاکچین و بیتکوین که خالی از لطف نیستند. بسیاری از بانکها و شرکتهای صنعتی و اقتصادی مهم کشور نیازمند برنامهنویسان سی++ هستند تا بتوانند در بحث بانکی برای توسعه دستگاههای پرداخت مانند Pos و ATM از این زبان و برنامهنویسان بهره ببرند. در صنایع بزرگ خودرو سازی و دیگر موارد نرمافزارهای مورد نیاز است تا با سرعت بسیار و بدون محدودی پلتفرمی پاسخگوی یک چرخهٔ تولید باشند تا بتواند زیرساختها و رابطهای یک شرکت بزرگ را مدیریت و آن را بهینه کند. در بسیاری از حوزههای صنعتی کشور شرکتهای غولپیکر در زمینهٔ تولیدات انبوه و سنگین که توسط ماشینآلات صورت میگیرد به دنبال برنامهنویسان سی و سی++ هستند که ممکن است به صورت معرف یا آشنا با آنها مواجه و استخدام شوید. شرکتهای سختافزاری و استارتآپهایی که در حوزهٔ الکترونیک و سختافزار فعالیت میکنند به دنبال برنامهنویسیان سی++ هستند تا بتوانند در حوزهٔ کاری خود اهداف خود را توسعه و شما را به عنوان مهرهای مفید پیش ببرند. شرکتهای توسعهدهندهٔ موبایل و خطوط تولیدی تلفنهای همراه داخلی گسترش یافته و به شدت نیازمند برنامهنویسان سی++ هستند که برخی از آنها مبادلات بینالمللی نیز دارند. در بخش حوزهٔ شهر سازی، مدیرت شهر و همچنین راهداری شرکتهایی هستند که برای تولید سیستمهای مدیریتی مانند مدیریت راهها و ترددهای خودرو و یا مدیریت ترافیک و موارد این چنینی به دنبال برنامهنویسان سی++ هستند. بسیاری از شرکتها و حتی تیمهای توسعه بر روی پلتفرمهای iOS و Android به صورت تخصصی سفارشی سازی و حتی ساخت و توسعهٔ اپلیکیشنهای ایرانی تمرکز دارند که جدیداً به لطف آگاهی از فریموُرکهایی مانند Qt به سمت این حوزه آمده و نیازمند سی++ کاران هستند. شرکتهای بازیسازی کشور ما که این سالها با پیشرفتهای خوبی مواجه شدهاند به دنبال برنامهنویسان سی++ هستند که بتوانند در این صنعت برای فرهنگسازی و توسعه صنعت بازی سازی جلو بروند. بسیاری از شرکتهای پنهان وجود دارد که به صورت بسیار مخفیانه در صنایع سهبعدی و پیشرفته در حال فعالیت هستند که محصولات خود را نه در ایران بلکه در خارج از آن آمریکا و دیگر کشورهای اروپایی به فروش میرسانند که به سفارش آنها بوده است. با دید سطحی به این مسائل نباید نگاه کنید، اگر آگهیهای استخدامی نمیبینید به خاطر این است که این زبان کار کُن می خواهد نه تَنبل! بنابراین شما باید به سراغ آن بروید چرا که بسیاری از شرکتهای بینالمللی فعالیتهای بزرگی انجام میدهند که هیچوقت از آنها خبر ندارید و به صورت کاملاً سفارشی و حساسیت کامل به دنبال برنامهنویسان این زبان هستند (چون میدانند یک سی++ کار هدفمند و با دید بازتری به توسعه نگاه میکند). چنین شرکتها معمولاً استخدام را به صورت رابطهای انجام میدهند و تعداشان هم کم نیست. ما میدانیم که شاید شما با دیدگاه اینکه حتماً باید نرمافزارهای کاربردی تولید کنید به قضیه نگاه میکنید، خوشبختانه فریمورک کیوت به قدری قدرتمند و پُخته شده است که میتوان هر محصول کاربردی در هر زمینهای را تولید کرد که از کارایی بسیار بهتری نسبت به دات نت بهرهمند است. در حوزهٔ امنیت، شبکه و موارد این چنینی شرکتهای بزرگ و Ispها نیازمند این زبان هستند. البته دلایل بسیاری وجود دارد که موجب میشود شرکتها از روی ناچاری به سراغ برنامهنویسان دیگر بروند، که من شخصاً آن را تجربه کرده ام ! در بسیاری از پروژهها که به عنوان مشاور فنی در آنها شرکت کرده بودیم متوجه آن شدیم شرکتها به خاطر عدم وجود برنامهنویس سی++ برای ادامهٔ چرخهٔ تولید خود مجبوراً سراغ برنامهنویسهای دیگر زبانها میروند. این امر به خاطر این است که واقعاً درصد تعداد برنامهنویسان این زبان نسبت به زبانهای دیگر به خاطر (راحت طلبی) و شاید عدم آگاهی از این زبان دور هستند. یکی از نکتههایی که اخیراً جالب بوده است، آن است که شما به واسطهٔ سیپلاسپلاس میتوانید حتی وبسایتهای مورد نیاز خود را بسازید! یک سیستم چند-منظوره طراحی کنید که در حوزههای قابل استفاده باشد. برخی از هماهنگیهایی که این زبان خود را به بهروز رسانیهای بسیار سریع در فناوری وفق داده است، پشتیبانی از ساختارهای چند-سکویی و کاملاً بومی با کارآیی بالا است که در حوزههای موبایل، دسکتاپ و وب میتوانید آن را مورد استفاده قرار دهید. از فناوریهای مربوط به فریمورکهای طراحی گرفته، تا امکان ساختوساز در قالب وباسمبلی، بلاکچین و دیگر موارد. یک نکتهٔ بسیار مهم که طی این سالها تجربه کردهام، این است که خیلی از شرکتها و خدمات دهندهها با این که در جریان مزایای این زبان هستند، مجبوراً به خاطر عدم وجود متخصص کافی از ابزارهای دیگر برای توسعهٔ کار خود استفاده میکنند. هرچند مشکلات این زبان تا به الآن شفاف شده است، اما بهروز رسانیها و توسعههای پی در پی آن موجب بهبودهای بسیار چشمگیری در آن نیز شدهاست. برخی از سوالاتی که علاقهمندان به این حوزه میپرسند در ادامه آمده است: من یک دانشجو هستم و رشتهٔ تحصیلی من کامپیوتر است، به برنامهنویسی با ++C علاقه دارم از کجا باید شروع کنم؟ اگر شما به قصدِ حرفهای شدن دنبال یادگیری این زبان هستید، همانطور که اشارهای شد مباحث پیش نیاز برای یادگیری این زبان مهم هستند و برای درک هرچه بیشتر این زبان بهتر است دانش خوبی در زمینهٔ تجزیه و تحلیل رفتار کامپایلر داشته باشید. علاوه بر این برای آشنایی با کامپایلر رفتار سیستمعامل و واکنشهای کامپایلری در سیستمعاملهای متفاوت بسیار مهم است. به عنوان مثال کامپایلر GCC بر روی ایستگاههای یونیکس تعبیه شده و برای خود قوانین و استانداردهایی را دارد. در کنار آن کامپایلر MSVC نوعی کامپایلر اختصاصی تحت ویندوز است که متناسب با ساختار و معماری ویندوز رفتار میکند. در نگاه اول آشنایی با آنها شاید الزامی به نظر نرسد، چرا که شما صرفاً به سمت یادگیری زبان، نحو (سینتکس)، ویژگیها، کتابخانهٔ پیشفرض و هستهٔ آن میپردازید. اما در بُعد ساخت و ساز یک محصول عالی اطلاعات شما در زمینههای مختلف لازم است کافی باشد. من یک دانشجو هستم اما متاسفانه رشتهٔ تحصیلی من کامپیوتر نیست، به برنامهنویسی با ++C علاقه دارم از کجا باید شروع کنم؟ این کار کمی دشوار است، در مرحلهٔ اول پیشنهاد ما این است که سراغ زبانهای برنامهنویسی دیگری بروید که نیازی نداشته باشد شما درگیر درک کامپایلر یا رفتارهای سیستمعاملی شوید. اما به هر حال اگر شما به هر نحوی میخواهید این زبان را یاد بگیرید چارهٔ کار تلاش مستمر و حوصله است. متاسفانه سیپلاسپلاس ذاتی مرموز دارد و آن این است که اگر بتوانید به آن مسلط شوید یک زبان با وفا و قدرتمندی خواهد بود که در هر زمینهای به نیازهای شما پاسخگو خواهد شد. اما اگر به هر دلیلی نتوانید با این زبان دوست شوید به طور بسیار مرموزی اعصابتان را به هم خواهد ریخت ? که البته طبیعی است چون سی++ تحت کامپایلرهای خود دستِ برنامهنویس را آزاد گذاشته و شما هستید که انتخاب میکنید کُد شما به چه شیوهای با توجه به هدف چگونه عمل کند. چقدر زمان لازم است تا من این زبان برنامهنویسی را یاد بگیرم؟ با توجه به ساختار زبان و رفتارهای کامپایلر میتوان گفت به قدری دامنهٔ سی++ گسترده است که تنها راه حل ممکن برای رسیدن به یک وضعیت مطلوب از دانش مرتبط با آن باید زمان مشخصی در نظر گرفته شود. ممکن است شما بتوانید در بازهٔ ۱ الی ۳ ماه مباحث مقدماتی این زبان را درک کنید. اما توجه داشته باشید پیشنیازات آن نیز نیازمند تحقیق، تجربه عملی و نتیجهگیری تئوری و علمی هستند. با توجه به اینکه شما (سریع، هوشمند با گیرایی بالا باشید) میتوانید در کمتر از ۶ ماه به یک پایداری تقریباً قابل قبول در حد مقدماتی این زبان برسید. استاندارد زبان را درک کنید و نحوهٔ برقراری ارتباط با کتابخانههای پیشفرض STL و غیره را تجربه کنید. برای کسب دانش و افزایش آن به میزان متوسط و به بالا نیازمند تلاش بسیار بیشتری خواهید بود که باید در قالب پروژههای عملی و واقعی صورت گیرد. متاسفانه سی++ به دلیل گسترده بودن چنان پیچیدگیهایی را دارد که تنها میتوان در موقع برنامهنویسی به صورت عملی (بر روی پروژههای واقعی) آن را تجربه کرد. آیا ارزش دارد من این زبان را یاد بگیرم؟ فرصت من کم است و میخواهم سریعاً به درآمدزایی برسم در همین ابتدا به شما میگویم که اگر صرفاً به درآمدزایی سریع فکر میکنید، سیپلاسپلاس گزینهٔ مناسبی برای این رویا نیست! اگر شما به عنوان یک برنامهنویس متوسط و به بالا به این زبان تسلط دارید، و حداقل میتوانید با یکی از کتابخانههای خوب آن ارتباط برقرار کنید، وقت آن است که با کتابخانههای قدرتمند این زبان وارد عمل شوید. کتابخانههایی مانند Boost، Poco، Qt و غیره از سری کتابخانههایی میباشد که امکانات بسیاری را در اختیار شما علاقهمندان این زبان قرار میدهند تا بتوانید در کمترین زمان ممکن به نیازهای خود دسترسی داشته و آن را پیاده سازی کنید. همهٔ آنها در ساخت و توسعهٔ محصول به شما کمک میکنند. فراموش نکنید که بارها گفتهام به زبانها، کتابخانهها و فناوریها به عنوان ابزار در داخل جعبهابزار خود بنگرید. توجه داشته باشید که لازمهٔ طراحی و توسعه یک محصول مفید (قابل قبول) در قالب MVP (کمینه محصول پذیرفتنی) مستلزم داشتن دانش طراحی محصول نیز میباشد. اما همه چیز اینگونه خلاصه نشده است و شما برای اینکه بتوانید یک محصول واقعاً قابل قبول را پیاده سازی کنید مسلماً باید آن را مجهز به قابلیتهای دیگری مانند منابع ذخیره داده و یا سرویسها و ماژولهایی کنید که بتواند به عنوان یک محصول کاربردی روی آن حساب کرد. آیا صرفاً با دانستن زبانهای برنامهنویسی و تسلط بر آن میتواند یک محصول استاندارد و سطح جهانی را به طور کامل تولید کرد؟ نظر من قطعاً خیر است! اگر شما واقعاً با دیدگاه یک سازنده، یک تولید کننده و مهندس تمام عیار در ذهن خود رویا پروری میکنید، در این صورت باید بدانید همه چیز در زبان خلاصه نمیشود! از نظر من حداقل مواردی که (به طور خیلی خیلی خلاصه و محدود) نیاز است تا یک متخصص بتواند پاسخگوی تصمیمگیری نقشهٔ توسعهٔ یک محصول برای مشتری در ابعاد مختلف و سطوح متفاوت از حوزههای موجود در قالب اصولی باشد به صورت زیر است که فرد یا یک تیم باید به آنها اشراف کافی داشته باشد: ۱- آشنا مبانی کامپیوتر که امر طبیعی (شامل درک و فهم مسائل و نحوهٔ حلشون متناسب با پلتفرم اجرایی محصول) ۲- آشنا به ساختار نوع محصول استاندارد در یک حوزه مثل: وب، آیاواس، اندروید یا دسکتاپهای مختلف مثل لینوکس، مک و ویندوز، اینترنت اشیاء و دیگر موارد. ۳- آشنا به فلسفهٔ بکاند و فرانتاند یا ترکیبی از این دو به همراه ابزارهای مناسب. ۴- آشنا به اصول طراحی UI/UX به عنوان یک نیاز و یک فاکتور مهم در ساخت محصولی که وابسته به عملکرد کاربر دارد و در حوزهٔ فرانتاند مهم و کاربردی هست. ۵- آشنا به اصول SOLID و امثالش مهم هستند. ۶- آشنا اصول برنامهریزی ساخت بانک اطلاعاتی، اینکه از چه بانک اطلاعاتیای استفاده کنی و چرا؟ ۷- آشنا به ارتباطات دادهای، جداول و ارتباط بین فیلدها، جداول و روشهای درست تبادل اطلاعات مابینی دادهها. ۸- آشنا و تسلط کافی به یک محیط توسعه و ادغام ابزارها و محیط طراحی برای هدف. ۹- آشنا به معماری ساختار و رابطهای برنامهنویسی (Api) ۱۰- آشنا به استانداردهای Http، درک و مدیریت درخواست، پاسخها و ... ۱۱- آشنا به الگوهای طراحی برنامهنویسی (DP) ۱۲- آشنا به روشهای نگهداری و آزمایش نرمافزار و کدها به خصوص درک مبحث Fault tolerance. ۱۳- آشنا به روشهای اطمینانسازی و ایمنسازی پردازشهای داخلی نرمافزار برای جلوگیری یا دشوار سازی نفوز و خرابکاری. ۱۴- آشنا به روشها و معماریهای احراز هویت و نحوهٔ ادغامش با نرمافزار مثل:JWT, OAuth, AWS و غیره... ۱۵- آشنا به نوع پارادایمهای زبان برنامهنویسی، در قالبهای (دستوری) Imperative و (اعلانی) Declarative مثل OOP، functional و دیگر موارد. ۱۶- آشنا به سبک معماری نرمافزاری (Microservice یا مثلاً Monolith) مزایا و معایب آنها. ۱۷- آشنا به سبک معماری طراحی مانند MVC در طراحی بدنهٔ محصول. ۱۸- آشنا به سبک و الگوهای طراحی ساختاری در بکاند مانند Builder، Abstract، Factory و غیره. ۱۹- آشنا به ساختار یک زبان (در صورتی که میخواهید جوابگوی مسائلِ پیش آمده باشید) کالبدشکافی زیرپوستی و عمیق یک زبان مهم است. ۲۰- آشنا و درک کامپایلرها و مفسرها، تفاوتها و شیوههای عملکردیشون نسبت به کدهای بهینه شده و عادی. ۲۱- آشنا و درک مدلهای مختلفی از سیستمهای توزیع شده مثل IaaS، PaaS، SaaS یا FaaS. ۲۲- آشنا به ابزارهای ساخت و فرآیند کاری اونها مثل CMake، NMake، QMake و غیره. ۲۳- آشنا به روشهای مدیریت وابستگیهای نرمافزار و ابزارهای لازم برای بستهبندی بهتر خروجی. ۲۴- آشنا به روشهای کدنویسی قابل آزمایش (Unit Test) و استفاده از ابزارهایی مثل CTest, GTest, Catch2 و غیره. ۲۵- آشنا به توسعهٔ آزمون محور (Test Driven- Development) ۲۶- آشنا به گامها و شرایط نسخهنگاری و مراحل توسعهٔ نرمافزار (SDP) ۲۷- آشنا به روشهای امنیت در کد و توسعه به شیوههای بررسی از طریق Fuzz-Test، Sanitizer، آنالیزرهای پویا و ایستا و غیره... ۲۸-آشنا به قوائد طراحی بر پایهٔ خدمات مبتدی بر معماری ابری برای خدمات پیامی، وبسرویسها، پردازش و غیره. ۲۹- در سطوح وب آشنا به مکانیزم شاخص بندی، فاکتورهای SEO و شیوههای درست بهبود صفحات وب. ۳۰- آشنا به روشهای به کار گیری و پیادهسازی ثبت کنندهٔ وقایع در دل محصول و روشهای بازخورد برای توسعهٔ بهتر به همراه مانیتورینگ، نظارت و تریسینگ. ۳۱- در شرایط لزوم آشنا به نحوهٔ به کار گیری و دلیل استفاده از فناوریهایی مثل Redis، Memcached و غیره. ۳۲- آشنا و درک صحیح از مفاهیم همزمانی (Concurrency) و روشهای به کار گیری آن نسبت به زبان برنامهنویسی و شرایط مناسب استفاده. ۳۳- آشنا به سبک و قوائد و ساختار زبانهای برنامهنویسی و فرآیند ساخت و ترجمه. ۳۴- و تا صدها گزینهٔ دیگر که میتوان در این بخش لیست کرد که اگر انتخاب شما زبانهای نزدیک به سیستم باشد این داستان در ادامهٔ این توضیحات سر به فلک خواهد کشید. با توجه به این موارد اگر بخواهید محصولی را بسازید که طبق استاندارد آن را توسعه و تولید کنید که در بستر سیپلاسپلاس شکل میگیرد، باید ابزارها و موارد پیشنهادی زیر را در اختیار داشته باشید و کار با آنها را تا حد نیاز بدانید: یک محیط توسعه یکپارچهٔ نرمافزار مانند Qt Creator، Xcode یا Visual Studio (پیشنهاد ما Qt Creator است) این محیط به عنوان IDE نیز یاد میشود. پلتفرم توسعه (سیستمعاملی) که قرار است محیط توسعهٔ یکپارچه خود را بر روی آن نصب و شروع به برنامهنویسی کنید را مشخص نمایید. اگر شما کاربر ویندوز هستید باید محیط توسعهٔ یکپارچهٔ شما مجهز به کامپایلر MSVC و یا نسخهٔ پورت شدهٔ GCC یعنی MinGW باشد. اگر شما کاربر مکاواِس هستید به صورت پیشفرض با نصب محیط توسعه کامپایلر Clang بر روی آن تعبیه خواهد شد. البته میتوانید به صورت سفارشی از کامپایلر GCC نیز استفاده کنید. در صورتی که کاربر لینوکس هستید کامپایلر GCC به صورت پیشفرض بر روی محیط توسعهی شما تعبیه خواهد شد. آشنا به دستورات ترمینال و یا کنسول در سیستمعاملهای لینوکس، مک و ویندوز در ساخت و سازهای دستوری مفید هستند و نیاز است آنها را بدانید. آشنا به Git و دستورات مربوط به آن در نگهداری و به اشتراکگذاری مخازن پروژه میتواند برای شما سودمند باشد. بر اساس پیشنها جهت محیط توسعه کتابخانهٔ Qt نیز پیشنهاد میشود (دلیل آن این است که این کتابخانه به شما کمک میکند تا بتوانید رابط کاربری نرمافزار (محصول) خود را پیاده سازی کنید). اگر هدف شما طراحی یک محصول استانداردی است که از شکل و ظاهر آنچنانی برخوردارد نیست بهتر است از ماژولهای پیشفرض Qt مانند Qt Widget برای طراحی آن استفاده کنید. این کار بسیار ساده است و نیازی برای داشتن دانش در رابطه با حوزههای JavaScript و QML ندارد. البته میتوانید با ترکیب CSS طراحی رابط کاربری برنامهٔ خود را بهبود ببخشید. بعد از این موارد نیاز است که شما هدف توسعهٔ خود را مشخص کنید، اینکه میخواهید توسعه دهندهٔ چه پلتفرمی باشید؟ تولید کننده برنامههای دسکتاپ بر روی ویندوز؟ یا لینوکس و مک؟ یا همهٔ آنها؟ خوشبختانه با توجه به قابلیتهای ذاتی سی++ و کیوت شما میتوانید برنامهٔ خود را تنها با داشتن محیط توسعهٔ خود بر روی پلتفرم مورد نظر خود کامپایل و خروجی بگیرید (البته به شرط اینکه از سرویسهای اختصاصی سیستمعاملی) استفاده نکرده باشید. البته دقت کنید اگر شما توسعهدهندهٔ اختصاصی برای فقط یک سیستمعامل خواهید بود، در این صورت نیازی به یادگیری مفاهیم یا رابطهای اختصاصی برنامهنویسی یک پلتفرم دیگر نخواهید بود. اگر مشتاق آن هستید که برای پلتفرمهای موبایل مانند آیاواس یا اندروید برنامه تولید کنید، موضوع کمی گستردهتر خواهد شد و حتماً باید ملزوماتی که در ابتدای مقاله به آن اشاره شده است را در نظر داشته باشید. برای مثال تولید یک نرمافزار iOS مستلزم آن است که شما علاوه بر داشتن دانش سی++ در رابطه با معماری و ساختار و همچنین قوانین، قوائد و ساختار نرمافزارهای مرتبط با اپل راداشته باشید. در Android نیز این چنین است. اگر شما تازه کار هستید پیشنهاد میکنیم هدف خود را فعلاً محدود بر یک پلتفرم خاص کنید، حتماً نیاز نیست اطلاعات خود را کامل و سپس اقدام کنید. برای مثال توسعه محصول بر روی ویندوز برای آغاز کار بسیار مناسب است و شما صرفاً بر روی این پلتفرم متمرکز خواهید بود. در نهایت شما محصول خود را با آزمایش وخطاهای بسیاری میتوانید تولید و با توجه به مستنداتی که در همین مرجع ارائه شده اس مستقر و برای کاربر نهایی ارائه کنید. برای اینکه بدانید مزایای این زبان در چیست و چه کتابخانههایی میتوانند مفید باشد و برخی از سوالات احتمالی که ممکن است به ذهن شما برسد این بخش را مطالعه کنید. برای نحوهٔ شروع کار با Qt این بخش را مطالعه کنید. جهت نحوهٔ نصب و راه اندازی محیط توسعه این بخش را مطالعه کنید. منابع فارسی یا زبان اصلی؟ پاسخ این سوأل بدون شک راحت است! زبان انگلیسی، زبان علم است، بنابراین هر آنچه که شما در زبانهای بومی و غیر انگلیسی مطالبه میکنید، ممکن است با محدودیتهای شدیدی مواجه شوید. بنابراین برای یادگیری محتوای علمی به شدت توصیه میشود به کمک مراجع انگلیسی آن را بیاموزید! من زبانم ضعیف هست، آیا باید به زبان انگلیسی تسلط کافی داشه باشم تا بتوانم زبانهای برنامهنویسی را یاد بگیرم؟ این یکی از سوألهای بسیار پر تکرار است که بارها با آن مواجه میشویم! در پاسخ باید صادقانه بگویم، شما به حداقلهای زبان انگلیسی واقعاً نیاز دارید! در حد این که متنهای عادی را بخوانید، آنها را متوجه باشید و بر اساس نگارش معنای صحیح جمله و واژهها را درک کنید. رفته رفته به آن عادت خواهید کرد و در آن نیز حرفهای خواهید شد. اما فراموش نکنید که زبانآموزی در کنار برنامهنویسی از لزومات است. در مورد واژههای تخصصی هم نگران نباشید، معمولاً واژههایی که معنای آنها را مابین جملات و کتابها نمیدانید، در مراجع و یا پانویسهای آنها تعریف میکنند. بسیاری از واژهها در قالب یک روش، مفهوم یا اصطلاح عنوان میشوند و شما باید به دنبال تعریف کامل آن باشید. به عنوان مثل، اصطلاح RAII در سیپلاسپلاس که به برخی از آنها در این بخش اشاره کردهام. من سن پایینی ندارم، آیا برای شروع کردن برای یادگیری سیپلاسپلاس دیر است؟ شاید من تجربهٔ سنیِ کافی، نسبت به کسانی که این سوأل را میپرسند نداشته باشم، اما نسبت به تجربهای که در مهندسی کامپیوتر و به خصوص ساختوساز و توسعهٔ محصولات نرمافزاری دارم، میتوانم به جرأت بگویم که این یک دغدغهٔ ذهنیای به حساب میآید که شاید در قالب و جنسِ ترسِ بیهوده از دست دادن زمان را به خود بگیرید. اما واقعیت آن است، تا زمانی که شما شروع نکنید، بله نمیتوانید! اما نکتهای که مد نظرم است بدانید، این است که در انتخاب زبانها، به خصوصی یادگیری سیپلاسپلاس، بهتر است بخشی از هدف و استعدادی که به آن دارید را هدف قرار دهید، (هدف مشخص و شفافی داشته باشید) چون خاصیت این زبان در چند-منظوره بودن آن است، و ممکن است شما را وسوسهٔ خود در همهٔ جوانب کند! که این باعث میشود شما هرگز به یک نقطهٔ شروع نرسید. به عنوان مثال، برای شروع بهتر است یک حوزه را انتخاب کنید و پیشبرورید، مانند: برنامهنویسی و طراحی اپلیکیشن در سیستمعامل ویندوز. یا برنامهنویسی در حوزهٔ موبایل، وب، بازیسازی، امبدها (سیستمهای درونسازی شده) و غیره... این بستگی به سلیقهٔ شما و نوع نیازی که در بازار میبینید خواهد داشت. در زیر منابعی را معرفی میکنم که به رایگان یا با کمترین هزینه میتوانید به آنها دسترسی داشته باشید: منابع استاندارد و رسمی زبان سیپلاسپلاس: https://en.cppreference.com https://isocpp.org برای یادگیری در سطوح مقدماتی وبسایتهای زیر پیشنهادات مناسبی هستند: https://www.geeksforgeeks.org/references-in-c http://www.cplusplus.com/reference https://www.tutorialspoint.com/cplusplus/cpp_references.htm https://www.learncpp.com در صورتی که میخواهید در حالت بسیار ساده، تصویری و در قالب برگههای تقلب به ویژگیهای زبان و کتابخانههای آن بپردازید، وبسایت زیر یک نمونه بسیار مناسب است: https://hackingcpp.com توجه کنید که خیلی از مباحث در وبسایتها ذکر نمیشود، نیاز است بعضی از کتابها را در نظر بگیرید و آنها را عمیقاً مطالعه کنید، بنابراین برای مطالعه به ترتیب سطح مقدماتی و پیشرفته را در زیر عنوان میکنم: Beginning C++ Programming Beginning C++20 A Tour of C++ The C++ Programming Language C++ Primer Programming: Principles and Practice Using C++ کتابهای معرفی شده به استانداردهای ۱۱، ۱۴، ۱۷ و ۲۰ اشاره میکنند. کتابهای پیشنهادی برای سطح پیشرفته: Effective C++ Professional C++ C++ Templates: The Complete Guide – Second Edition Modern C++ Programming Cookbook Hands-On System Programming with C++۱۷ C++ High Performance Optimized C++ در صورتی که نیاز به کسب دانش بیشتر در حوزهٔ سطح پایین، سختافزار، معماری و ساختارهای نرمافزاری دارید کتابهای زیر بسیار مفید هستند: Computer Organization & Design RISC-V / ARM / MIPS / x86 Software Architecture with C++ در صورتی که تجربیات و نوشتههای خودم رو در این باره نیاز دارید به صورت زیر دستهبندی کردم که به ترتیب پیشنهاد میکنم مطالعشون کنید: اگر به دنبال مشاورهها، منابع یا مقالات و توصیههای فارسی یا انگلیسی من هستید، پیشنهاد میکنم در همین وبسایت، یوتیوب، گیتهاب و یا کانال تلگرامی من ملحق بشید. من هر جا که باشم، با شناسهٔ KambizAsadzadeh اگر در حد توانم باشد شما را راهنمایی خواهم کرد.
-
2 امتیازدر سالی که گذشت (۲۰۲۲)، سیپلاسپلاس محبوبترین زبان برنامهنویسی با رشد شاخص محبوبیت ۴.۶۲٪ انتخاب شد! جایزه زبان برنامهنویسی سال TIOBE به ++C تعلق گرفت! این جایزه به زبان برنامهنویسی تعلق میگیرد که بیشترین افزایش محبوبیت را در یک سال تجربه کرده است. شاخص TIOBE میزان محبوبیت زبانهای برنامهنویسی را اندازهگیری میکند. با این حال، قبل از نتیجهگیری، توجه به این نکته مهم است که Index (شاخص) نه چیزی در مورد کیفیت یک زبان برنامهنویسی میگوید و نه ادعا میکند. این رتبهبندی با تجزیه و تحلیل تعداد مهندسان ماهر در یک زبان خاص، تعداد دورههای آموزشی در آن زبان و تعداد فروشندگان شخص ثالثی که محصولات یا خدمات مرتبط با آن زبان را ارائه میدهند، محاسبه میشود. این فهرست ماهانه بهروز میشود و بر اساس دادههای موتورهای جستجوی محبوب مانند گوگل، بینگ و یاهو است. جایزهٔ زبان برنامهنویسی سال TIOBE در ژانویه هر سال بر اساس رتبهبندی سال قبل اعلام میشود. سیپلاسپلاس یک زبان برنامهنویسی در سال ۲۰۲۲ انتخاب شد که با محبوبیت رشد ۴.۶۲ درصد و بیشترین رشد انتخاب شده است. این زبان برنامهنویسی سطح بالا با کارایی بالا و چندمنظوره برای توسعهٔ نرمافزارهای سیستمی، برنامههای کاربردی و بازیهای ویدیویی با انعطافپذیری و قابلیت کنترل سطوح پایین است. این زبان در نوامبر ۲۰۲۲ جاوا را پشتسر گذاشت و به رتبهٔ سوم شاخص رسید و محبوبیت آن به طور پیوسته در حال افزایش است. نایب قهرمان در سال ۲۰۲۲ به ترتیب C با رشد ۳.۸۲ و پایتون با ۲.۷۸ درصد رشد بودهاند.
-
2 امتیازیک سوأل بسیار مهم و پر مخاطب در بارهٔ زبانبرنامهنویسی سیپلاسپلاس در سالهای اخیر این است که «آیا جایگزینی برای این زبان وجود دارد و یا قابل جایگزین است»؟ در بسیاری از پاسخها نشان از گزینههایی مانند Go، Rust و D دیده میشود که بهتر است نسبت به نظرات متخصصهای برنامهنویسی به این موضوع پرداخته شود، ابتدا باید در نظر گرفت که هر ابزاری میتواند جایگزینی داشته باشد اما شرایط و نحوهٔ استفادهٔ آن در رابطه با نیاز متفاوت است. اخیراً سوألات زیادی در این موضوع دیده شده است که میگویند، Rust یک زبان برنامهنویسی ایمن، سریع و سیستمیِ جایگزین برای سیپلاسپلاس است! اما آیا واقعاً اینگونه است یا صرفاً ما بر اساس احساسات و اشتیاق به بهروز شدن به این موضوع میپردازیم؟ پاسخ برای این سوأل به صورت زیر در مدلهای مختلف میتواند مطرح شود که نتیجهگیری و تصمیم از خلاصهٔ آن به عهدهٔ خودِ شماست. من بر این باورم که زبانهای برنامهنویسی همه و همه در حال بهروز رسانی و بهتر شدن نسبت به نسخهها، استانداردها، و نسلهای گذشتهٔ خودشان هستند و به هیچ عنوان هیچ زبانی تا به امروز به طور جدی منسوخ شده اعلام نشده است. برای درک این مطلب بهتر است ابتدا به واژهٔ «منسوخ شده» یا «Deprecated» بپردازیم، این واژه زمانی مورد استفاده قرار میگیرد که شرایط زیر بر آن حاکم باشد: گزینهٔ مورد نظر به طور رسمی از طرف سازنده، پشتیبان یا صاحب آن بد دانسته شده و رسماً کنار گذاشته شود. گزینهٔ مورد نظر بهروز رسانی نشود و آخرین بهروز رسانی آن نیز شامل مشکلاتی باشد که بعد از مدتها نیز حل نشده باشد. گزینهٔ مورد نظر دیگر مورد استفاده قرار نگیرد و کاربردی هم در بین رقبای خود نداشته باشد. گزینهٔ مورد نظر دیگر پشتیبانی نشود و به قولی مُرده باشد. گزینهٔ مورد نظر به علاوهٔ این که شامل این موارد میشود، باید دارای یک جایگزین مناسب و عالی باشد. با توجه به این معیارها و با در نظر گرفتن رسالت هر یک ابزارها باید به آن توجه کرد که هر زبان یا ابزار برنامهنویسی خارج از این، در مرحلهٔ پیشرفت قرار گرفته است که آن نشان دهندهٔ زنده بودن و کاربردی بودن آن است. از طرفی، زبانی مثل سیپلاسپلاس جایگزین نمیشود چرا که هیچ یک از دلایل و معیارهای بالا شامل حال آن نمیشود، اتفاقاً برعکس این زبان دارای ویژگیهای معیاری زیر است: این زبان به طور رسمی توسط کمیتهٔ استانداردسازی که متعلق به هیچ یک از شرکتهای غول صنعتی و یا خصوصی نمیباشد پشتیبانی میشود. این زبان به طور مداوم در حال بهروز رسانی است و کاربردهای چند-منظوره و همه جانبهٔ خود را داراست. این زبان از ویژگیهای از ویژگیهای بسیار خوب به همراه سریعترین بازدهیها را داراست. این زبان رقیبهای بسیاری دارد، اما هیچ کدام از آنها هنوز در عمل و دامنهٔ وسیعی موفق به نمایش عملکرد بهتری نبودهاند. این زبان همانند دیگر ابزارها دارای مشکلاتی است، اما با توجه به پوشش و پشتیبانی از ویژگی BC در روند استانداردسازی و بهروز رسانی به خوبی از پس آنها بر آمده است. برای مثال، زبان جاوا یکی از بهترین زبانهای برنامهنویسی است و خیلی از شرکتها مانند گوگل در سیستمهای توزیع شده از آن استفاده میکنند. اما به معنای این نیست که به سرعت سی++ میرسد و در حد مقایسه با آن است. این زبان میتواند دهها و صدها برابر کندتر از سی++ باشد و این مربوط به طراحی، ساختار و مسائل مربوط به زبان است. از طرفی سیپلاسپلاس محبوب است زیرا که ویژگیهای زیر را دارد و طی سالهای بسیاری آن را ثابت کرده است: کارآیی (پرفرمنس) و سرعت فوقالعادهٔ این زبان، البته خیلی از زبانها ادعا میکنند که همچین ویژگیای را دارند که در عمل نتیجهٔ جالبی مشاهده نمیشود. ذاتِ چند-سکویی و چند-منظوره بودن آن، حداقل همهٔ سیستمها میتوانند کدهای سی++ را کامپایل و اجرا کنند. این زبان به راحتی میتواند با زبانها و فناوریهای دیگری ارتباط برقرار کرده و با آنها تعامل داشته باشد. این زبان به عنوان یکی از کممصرفترین زبانهای برنامهنویسی از نظر مصرف انرژی محسوب میشود. بسیاری از مهندسین این زبانها را به صورت مقطعی و بارها دیده و با آن آشنا هستند. کتابخانههای پیشفرض استاندارد STL و دیگر کتابخانههای سی++ بسیار قدرتمند و گسترده هستند. کتابخانههای نوع سوم (Third-Party) بسیار قدرتمند و بهروز هستند. اولویتهای سیستمهای یونیکس و حتی ویندوز اکثراً بر روی C و ++C است و بازنویسی آنها با زبانهای دیگر هزینهٔ بسیاری را به ارمغان میآورد. بسیاری از وابستگیهای ایجاد شده در سالهای بسیار طولانی بر اساس سی و سی++ بوده و بازنگری و بازنویسی آنها مشروط بر این که رابطها باید بازنویسی شود بسیار سخت و کاری مشابه اختراع دوبارهٔ چرخ است. عملکرد تا حدی قابل پیشبینی است و میتواند آن را درک کرد، چیزی که در زبانهایی مانند جاوا، سیشارپ و گو نمیتواند پیشبینی کرد چرا که پیشبینی چرخهٔ GC دشوار است، هیچ رقیب جدیای در این باره در سطح سی++ وجود ندارد که مدیریت حافظه را برای شما در قالب یک RAII ارائه کند، هرچند در مورد Objective-C و Rust میتوان آنها را به صورت جداگانه مورد بررسی قرار داد و نه عین آن. پشتیبانی از پارادایم (سبک)های طراحی را سی++ به خوبی پشتیبانی میکند، برای مثال برنامهنویسی عمومی در زمان کامپایل را به خوبی ارائه میکند. پشتیبانی از برنامهنویسی سیستمی و سطح پایین در این زبان یک مزیتی دیگری است که در کنار تمامی ویژگیهای سطح بالای خود ارائه میکند. اما در این میان زبانهایی مثل Rust، Go، Swift و غیره ادعای جایگزینی را دارند اما ادعاهای فنی به تنهایی کافی نیستند، در دسترس بودن گسترده از جامعه به اندازهٔ کافی به همراه جامعهٔ معتمد به آن مهم است. علاوه بر ویژگیهای فنی زبان سی++، یک نقطه قوت بسیار مهم این زبان در بحث غیر فنی آن است، در واقع در پشت این زبان نه یک پیادهسازی محدودی وجود دارد و نه یک سازمان که در آینده در مورد آن تصمیم بگیرد و آن را کنترل کند. در حالی که تمامی زبانهای مطرح و ادعا کننده داخل یک چهارچوبی کنترل میشوند که به شدت آیندهٔ آنها را تیره و تار میکند. به طور کلی آزاد بودن یک ابزار و قدرت یک جامعه فارغ از جغرافیا، سازمان، نژاد و زبان یک قدرت بسیار خارقالعادهای را برای یک ابزار به ارمغان میآورد که به تنهایی بسیار اهمیت دارد. در این اواخر بسیاری از مهندسین به فکر بازنویسی بسیاری از موارد شدن و تحقیقات نشان میدهد ابزارهایی گرافیکی بسیار قدرتمند و سریع که اخیراً طراحی شدهاند، مانند وُلکان که با سی++ نوشته شده است زمانی میتوانند با راست و زبانهای دیگر امروزی بازنویسی شوند که یک سیستمعامل جدید با زبانهای جدید ساخته شود! بنابراین صرفاً میتوان یک نسخهٔ Wrapper یا همان (پوشنده) چرا که تقریباً همهٔ سیستمعاملهای مدرن امروزی با زبانهای سی و سی++ نوشته شدهاند. از طرفی تولید یک سیستمعامل بسیار پر خطر است و سرمایهگذاری کلان، زمان و هزینههای بسیاری را میطلبد و تا زمانی که چنین نرمافزارهایی تحت سلطهٔ زبانهایی مانند سی++ قرار گرفته باشند پادشاهی سیپلاسپلاس ادامه خواهد داشت. نکتهٔ پایانی من معتقدم هر ابزار و زبانهای برنامهنویسی جایگاه و شرایط استفادهٔ خودشان را شامل میشوند، دقیقاً مانند ابزارهای موجود در یک جعبهابزار بهتر است ابزارهای خود را طوری بچینید که در جای لازم از مناسبترین آنها استفاده کنید. با این حال زبانها و ابزارهای مانند سی یا سی++ طی سالها ثابت کردهاند که معمولاً در همهٔ حوزهها غالب هستند و میتواند هر کاری را که بخواهید با آنها انجام دهید و یا با یک جایگرین مناسب آن را مدیریت کنید و این بستگی به مهارت و انتخاب شخصی شما دارد. همچنین صحبتهای اخیر کمیتهٔ استانداردسازی در رابطه با نحو ۲ از سیپلاسپلاس میتواند مفهوم خوبی در آیندهٔ این زبان باشد. مقالات مرتبط با این موضوع که میتواند به عنوان مکملی از پیش تعریف شده برای شما مفید باشد:
-
2 امتیازقسمت اول: Block Environment Block (PEB) از زمان معرفی Win2k (ویندوز 2000) در ویندوز وجود داشته است و از آن زمان به بعد نسخه های جدیدتر ویندوز بهبود یافته است. در نسخه های قبلی ویندوز ، انجام برخی کارهای ناخوشایند مانند پنهان کردن ماژول های بارگذاری شده موجود در یک فرآیند (برای جلوگیری از پیدا شدن آنها - بدیهی است که این چیز زیبایی نیست) سوءاستفاده می شود. چرا این موضوع مهم را “Process Environment (PEB)” مینامیم؟ PEB ساختاری است که اطلاعات مربوط به روند فعلی را تحت مقادیر خود نگهداری می کند - برخی از زمینه ها (فیلد ها یا داده ها) خود ساختارهایی هستند که حتی داده های بیشتری را در خود جای می دهند. هر فرآیندی PEB خاص خود را دارد و هسته Windows نیز به PEB هر فرآیند حالت کاربر دسترسی دارد تا بتواند داده های ذخیره شده در آن را پیگیری کند. این ساختار از کجا می آید؟ ساختار PEB از هسته ویندوز ناشی می شود (اگرچه در حالت کاربر نیز قابل دسترسی است). PEB از Block Environment Thread (TEB) ناشی می شود که معمولاً به آن Thread Information Block (TIB) نیز گفته می شود. TEB مسئول نگهداری اطلاعات مربوط به thread فعلی است - هر thread ساختار TEB خاص خود را دارد. آیا می توان از Block Environment Block یا Block Environment Block برای اهداف مخرب سوء استفاده کرد؟ البته آنها می توانند! در واقع ، آنها در گذشته برای اهداف مخرب مورد سوء استفاده قرار گرفته اند ، اما مایکروسافت طی سالهای اخیر تغییرات زیادی را برای جلوگیری از این امر انجام داده است. مثالی در گذشته بود که روت کیت ها یک DLL را به یک فرایند در حال اجرا تزریق می کردند و سپس به ساختار PEB فرآیند فعلی که به آن تزریق کرده بودند دسترسی پیدا می کردند (ساختار PPEB اشاره گر به ساختار PEB است) تا بتوانند لیست را پیدا کنند. از ماژول های بارگذاری شده و ماژول خود را از لیست حذف کنید ... بنابراین هنگامی که کسی ماژول های بارگذاری شده فرآیند آسیب دیده را برشمارد ، ماژول تزریق شده را از نظر پنهان می کند. این به عنوان وصله حافظه شناخته می شود زیرا شما می توانید با وصله PEB حافظه را تغییر دهید. تلاش مایکروسافت برای این کاهش رفتار این بود که از تغییر دستی لیست که نشان دهنده ماژول های بارگذاری شده در حالت کاربر است جلوگیری کند-شما همچنان می توانید برای خواندن داده ها در حالت کاربر به آن دسترسی داشته باشید و همچنان می توانید حافظه را از حالت کرنل وصله کنید. پایان قسمت اول ?
-
2 امتیازمراحل ساخت برنامه در زبان سیپلاسپلاس پیش نویس ۰.۶ قبل از هر چیز به اینفوگرافی زیر توجه کنید که مراحل ساخت برنامه در سیپلاسپلاس را نشان میدهد. مقدمهای بر همگردانی (کامپایل) و اتصال (لینک کردن) این سند مرور مختصری در رابطه با مراحل را برای شما فراهم میکند تا به شما در درک دستورات مختلف برای تبدیل و اجرای برنامهٔ خودتان کمک کند. تبدیل مجموعهای از فایلهای منبع و هدر در سیپلاسپلاس به یک فایل خروجی و اجرایی در چندین گام (به طور معمول در چهار گام) پیشپردازنده (Preprocessors)، کامپایل و گردآوری (Compilation)، اسمبلر (Assmbler) و پیوند دهنده (Linker) تقسیم میشود. قبل از هر چیز اگر در محیط توسعهٔ Qt Creator داخل فایل .pro مقدار زیر را وارد کنید، تا بتوانید فایلهای ساخته شدهٔ موقت در زمان کامپایل را مشاهده کنید. QMAKE_CXXFLAGS += -save-temps این دستور اجازهٔ آن را خواهد داد تا فایلهایی با پسوند .ii و .s در شاخهٔ بیلد پروژه تولید شوند که در ادامه به آنها اشاره شده است. تعریف پیشپردازنده پیشپردازندهها (Preprocessors) درواقع دستوراتی هستند که اجازه میدهند تا کامپایلر قبل از آغاز کردن مراحل کامپایل دستوراتی را دریافت کند. پیشپردازندهها توسط هشتگ (#) مشخص میشوند این نماد در سی++ مشخص میکند که دستور فوق از نوع پیشپردازنده میباشد که نتیجهٔ آن در قالب ماکرو (Macro) در دسترس خواهد بود. برای مثال ماکروی __DATE__ توسط پیشپردازندهها از قبل تعریف شده است که مقدار تاریخ و زمان را بازگشت میدهد. بنابراین هرکجا که از آن استفاده شود کامپایلر آن را جایگزین متن خواهد کرد. در شکل زیر مرحلهای که از پیشپردازندهها استفاده میشود آمده است: پیشپردازنده، کامپایل (گردآوری کردن)، لینک (پیوند کردن) و ساخت برنامه اجرایی فرایند تبدیل مجموعهای از فایلهای متنی هِدر و سورس سی++ را «ساخت» یا همان Building میگویند. از آنجایی که ممکن است کُد پروژه در بسیاری از فایلها هدر و سورس سی++ توسعه و گسترش یابدمراحل ساخت در چند گام کوچک صورت میگیرد. یکی از رایجترین موارد در مراحل گردآوری (ترجمهٔ یک کد سیپلاسپلاس به دستورالعملهای قابل فهم ماشین) است. اما گامهای دیگری نیز وجود دارد، پیشپردازنده و لینک (پیوندها) این بخش به طور خلاصه توضیح میدهد که چه اتفاقی در هر یک از مراحل رُخ میدهد. یک کامپایلر یک برنامهٔ خاص است که پردازش اظهارات (دستورات) نوشته شده در یک زبان برنامهنویسی خاص را به یک زبان ماشین که قابل فهم برای پردازنده میباشد تبدیل کند. به طور معمول یک برنامهنویس با استفاده از یک ویرایشگر که به محیط توسعهٔ یکپارچهٔ نرمافزار (IDE) مشهور است توسط زبان برنامهنویسی مانند ++C دستورات (اظهارات) را مینویسد. فایل ایجاد شده با نام (filename.cpp در زبان برنامهنویسی سیپلاسپلاس) شامل محتوایی است که معمولاً به عنوان دستورات برنامهنویسی سطح بالا نامیده میشود. سپس برنامهنویس کامپایلرِ مناسب برای زبان برنامهنویسی مانند سی++ را اجرا میکند و نام فایلهایی که حاوی دستورات هستند را برای کامپایل مشخص میکند که این انتخاب و مشخص سازی توسط IDE به راحتی قابل مدیریت است. پس از آن، کار کامپایلر این است که فایلهای منبع .cpp را جمع آوری کرده و پیشپردازندهها را بررسی کند تا دستورات احتمالی را اجرا نماید که نتیجهٔ این مرحله در فایلی با پسوند .ii ر قالب filename.ii تولید میشود که در این فرایند نیز خط به خط کُدهای موجود در آنها را بررسی میکند تا خطاهای احتمالی نحو (سینتکس - Syntax) بررسی میشود و آنها را به طور ترتیبی به دستورالعملهای سطح ماشین تبدیل کند. توجه داشته باشید که هر نوع پردازندهٔ کامپیوتر دارای مجموعهای از دستورالعملهایِ ماشین خودش است. بنابراین کامپایلر تنها برای سی++ نیست، بلکه برای اهداف و مقاصد خاص هر پلتفرم است. پس کدهایی که توسط پیشپردازنده سیپلاسپلاس به زبان اسمبلی برای معماری مورد نظر در پلتفرم مقصدترجمه شدهاند نتایج آن در فایلی با پسوند .ss در قالب filename.ss قابل نمایش هستند که در حالت عادی قابل رویت نیست. توجه داشته باشید که باید در این مرحله باید مشخص شود برنامه قرار است توسط چه نوع پردازندهای تحتِ چه نوع معماری مونتاژ (اسمبل) شود. برای مثال پردازندهها با انواع معماریهای مختلف وجود دارند که برخی از آنها به صورت x86-x64، x64، ARMv7، aarch64 غیره ... میباشند. شکل یک (کامپایل یک فایل منبع ++C) مرحلهٔ سوم را در نظر داشته باشید که عمل کامپایل فایل سیپلاسپلاس در دو مرحله قبلی یک فایل اجرایی را تولید نمیکند. برنامهای که توصیف شده است، احتمالاً توابعی را در رابطهای برنامهنویسی (API) و یا توابع ریاضی یا توابع مرتبط با I/O را فراخوانی کند که ممکن است شامل فایلهای هدر مانند iostream یا fstream و حتی ماژولهای دیگری که در زبان تعبیه شدهاند را داشته باشد که فایل تولید شده توسط کامپایلر در این مرحله یک فایل شیء نامیده میشود که با پسوند .o به صورت filename.o تولید خواهد شد که علاوه بر دستورالعملهای تبدیل شده به کد ماشین، شامل توابع و دستورالعملهای خارجی نیز میباشد. هرچند در این مرحله دستورات تبدیل به دستورالعملهای قابل فهم توسط پردازنده شدهاند اما فعلاً قابل اجرا نیستند چرا که باید این توابع خارجی افزوده شده را به آن لینک کرد که در مرحلهٔ بعد یعنی مرحلهٔ چهارم اتفاق میافتد. در نهایت مرحلهٔ چهارم فایل با پسوند .o که شامل کدهای تولید شده توسط کامپایلر به زبان ماشین است که پردازندهها میتوانند این دستورات را درک کنند که همراه با کدهای تولید شدهٔ هر کتابخانهٔ دیگری که مورد نیاز است توسط لینکر (لینک شده) و در نهایت جهت تولید یک فایل اجرایی مورد استفاده قرار میگیرند که نوع آن فایل از نوع اجرایی یا در واقع Executable File خواهد بود. شرح کامل فرایند ساخت فایل اجرایی اکثر پروژهها دارای مجموعهای از فایلهای هدر سی++ هستند، که امکان ماژولار شدن در آن را فراهم میکند و مجموعهای از آن میتواند به عنوان بخشهای کوچکی از برنامه محسوب شوند. برای ساخت چنین پروژههایی هر فایل سیپلاسپلاس باید کامپایل شود و سپس فایلهای ساخته شده در قالب شیء (آبجکت) باید همراه توابع و کتابخانههای دیگر لینک (پیوند) شوند. البته هر گام از مراحل کامپایل شامل یک مرحله پیشپردازنده است که دستورالعمل # عمل تغییرات و اصلاحیهها را در فایل متن اعمال میکند. شکل زیر فرایند ساخت چند فایل به صورت همزمان را نشان میدهد: در ادامهٔ این مقاله، مطلبی مرتبط با تنظیمات بیشتر از کامپایلر آمده است که میتوانید آن را مورد مطالعه قرار دهید.
-
1 امتیازاگر شما توسعه دهندهٔ ++C هستید، توصیه میکنم این سری از مقالات را دنبال کنید زیرا در این تاپیک قصد دارم به چکیدهای از آخرین تغییرات مرتبط با سیپلاسپلاس پیشرفته اشاره کنم. بنابراین در بخش اول، مهمترین موارد منسوخ شده، اشکلات رفع شده و ویژگیهای جدید در استانداردهای اخیر را پوشش خواهیم داد که به صورت جزئی خواهد بود و سپس نسبت به هر کدام در مقالات جداگانه به کاربردهای پیشرفتهتر و جزئیات بیشتری اشاره خواهیم کرد. قبل از شروع، اگر میخواهید به لیستی از تغییرات و ویژگیهای کامل در استانداردها دسترسی داشته باشید به مقالهٔ زیر مراجعه کنید. در مقالهٔ فوق به لیست ویژگیهای جدید در استاندارد ۱۱، ۱۴، ۱۷ و ۲۰ اشاره شده است. در نظر داشته باشید که بزرگترین بهروز رسانی سی++ در ده سالِ اخیر مربوط به استاندارد ۲۰ است. این نسخه از زبان تقریباً 2.5 برابر بزرگتر از سی++ ۱۰ سال پیش است! این در حالی است که استاندارد ۱۷ تقریباً ۸۰٪ بزرگتر از استاندارد ۰۳ است. به عنوان مثال، طبق مستندات رسمی پیشنویسهها تغییرات استاندارد از ۸۷۹ صفحه به ۱۸۳۴ صفحه در این استاندارد رسیده است! چیزی حدود ۱۰۰۰ صفحه بیشتر از نسخههای قبلی ? تمامی این بهبودها خبر از بهتر شدن و در عین حال پیچیده شدن زبان اما همراه با سادهتر و سریعتر شدن آن میدهد. اما مشکلی که میتواند رخ دهد در این است که یادگیری آن و بهروزرسانی کدها نیز میتواند دردسر ساز باشد. بنابراین، برای پوشش دادن جزئیات و بهروزرسانیهای بیشتر در این مقاله سعی خواهم کرد که مهمترین موارد را معرفی کنم. جزئیات ++C نسخه ۱۷ (بهبودها و تغییرات) بیایید به آرامی شروع کنیم، امروز ما به عناصر حذف شده و یا به موارد بهبود یافتهٔ کتابخانه استاندارد بپردازیم. معرفی به صورت سلسله مراتبی عناصر حذف شده و توسعه یافته (در این بحث) شفاف سازی در زبان قالبها ویژگیها تغییرات اول کتابخانه تغییرات دوم کتابخانه مستندات و لینکها قبل از هر چیز، اگر شما خودتان میخواهید استاندارد جدید را کاوش کنید آخرین پیش نویسه را در این بخش مطالعه کنید. در صورتی که میخواهید بدانید کدام کامپایلر از ویژگیهای جدید پشتیبانی میکند، در این بخش آن را پیگیری کنید. علاوه بر این، لیستی از توصیفهای مختصر از تمامی ویژگیهای زبان سیپلاسپلاس ۱۷ تهیه شده است که در این بخش میتوانید آن را ببینید که در قالب PDF از طرف مرجع رسمی میباشد. مواردی که ترجیح داده شده است که حذف شوند حذف تریگراف تریگرافها کاراکترهای ویژه ترتیبی هستند که در موقع عدم پشتیبانی سیستم از نوع ۷ بیتی اَسکی (ASCII) همانند ایزو 646 استفاه شوند. برای مثال =?? کاراکتر ویژهای مانند # تولید شده را در قالب -?? تولید میکند. تمامی مجموعه کاراکترهای اصلی سیپلاسپلاس در قالب 7 بیتی اسکی قرار دارند. موضوع فوق به ندرت مورد استفاده قرار میگیرد، بنابراین حذف آن ممکن است به ترجمه ساده کد کمک کند. اگر شما میخواهید اطلاعات بیشتری در رابطه با کارآیی تیرگرافها در سی++ کسب کنید به این لینک مراجعه کنید. ---------------------------------------------------------------------------- | trigraph | replacement | trigraph | replacement | trigraph | replacement | ---------------------------------------------------------------------------- | ??= | # | ??( | [ | ??< | { | | ??/ | \ | ??) | ] | ??> | } | | ??’ | ˆ | ??! | | | ??- | ˜ | ---------------------------------------------------------------------------- شما جزئیات بیشتر را میتوانید در سند N4086 بیابید. اگر شما واقعاً به هر نحوی به گرافها در ویژوال استودیو نیاز دارید، نگاهی به مشخصه /Zc:trigraphs در بخش پیکربندی داشته باشید. همچنین، کامپایلرهای دیگر ممکن است مواردی را پشتیبانی نکنند. وضعیت انجام شده کنونی در کامپایلر های GCC:5.1 و Clang:3.5 میباشد. حذف کلمه کلیدی register کلمه کلیدی register در استاندارد 2011 سیپلاسپلاس منسوخ شده است و دیگر استفاده از آن معنایی ندارد. این کلمه کلیدی در حال حاضر حذف شده است. این کلمه کلیدی محفوظ است و ممکن است در نسخه های بعدی باز نویسی شود (مثلا autokeyword به عنوان یک چیز قدرتمند مجددا مورد استفاده قرار گرفته است). جزئیات بیشتر در رابطه با این مورد در P0001R1 قابل مشاهده است. البته فعلا در MSVC انجام نشده است اما در کامپایلرهای GCC 7.0 و Clang 3.8 انجام شده است. حذف Operator++ bool این اپراتور برای زمان بسیار زیادی است که منسوخ شده است! در سی پلاس پلاس ۹۸ تصمیم بر آن گرفته بودند که از آن استفاده کنند اما در نسخه ۱۷ سیپلاسپلاس کمیته موافقت خود را جهت حذف آن از زبان اعلام کرده است. جزئیات بیشتر در رابطه با این مورد در P0002R1 قابل مشاهده است. البته فعلا در MSVC انجام نشده است اما در کامپایلرهای GCC 7.0 و Clang 3.8 انجام شده است. حذف مشخصات استثنایی از استاندارد ۱۷ در سی پلاس پلاس ۱۷، مشخصات استثنایی بخشی از نوع سیستمی خواهند بود (به P0012R1 نگاه کنید). با این حال، استاندارد شامل مشخصات استثنایی قدیمی و منسوخ شده اند که به نظر غیرعلمی و غیرقابل استفاده است. void fooThrowsInt(int a) throw(int) { printf_s("can throw ints\n"); if (a == 0) throw 1; } کد بالا در سیپلاسپلاس ۱۱ رد (منسوخ شده است). تنها اعلامیه استثنایی علمی throw() است، به این معنی است که این کد چیزی را در قالب throw انجام نخواهد داد. اما از سیپلاسپلاس ۱۱ به اینور، برنامه نویسان توصیه کرده اند که کسی از آن استفاده نکند. برای مثال در کامپایلر Clang 4.0 شما باید خطای زیر را دریافت کنید: error: ISO C++1z does not allow dynamic exception specifications [-Wdynamic-exception-spec] note: use 'noexcept(false)' instead جزئیات بیشتر در رابطه با این مورد در P0003R5 قابل مشاهده است. البته فعلا در MSVC انجام نشده است اما در کامپایلرهای GCC 7.0 و Clang 3.8 انجام شده است. حذف auto_ptr این یکی از به روز رسانیهای خوبی است که در سیپلاسپلاس ۱۱، ما اشاره گرهای هوشمند را دریافت کردیم : unique_ptr,shared_ptr و weak_ptr. با تشکر از این حرکتی که کمیته انجام داده بود، معنای واقعی این به روز رسانی در این بود که زبان میتواند پشتیبانی مناسبی از انتقال منابع منحصربفرد را داشته باشد. در این میان auto_ptr یک چیز قدیمی و نادرست در زبان بود به نا به دلایلی auto_ptr در این جا منسوخ شده است و باید به صورت خودکار به unique_ptr تبدیل شود. توجه داشته باشیم که auto_ptr مدت کوتاهی است که از سیپلاسپلاس ۱۱ به اینور منسوخ شده است و بسیاری از کامپایلر ها منسوخ شدن آن را گزارش میدهند که به صورت زیر خواهد بود: warning: 'template<class> class std::auto_ptr' is deprecated در حال حاضر آن به وضعیت نامناسب تبدیل شده است، و اساساً کد شما کامپایل نخواهد شد. در اینجا خطا از طرف MSVC 2017 زمانی که از گزینه /std::c++latest استفاده کنید اعلام خواهد شد. error C2039: 'auto_ptr': is not a member of 'std' اگر شما نیاز به کمک از تبدیل از auto_ptr به unique_ptr دارید، میتوانید Clang Tidy را بررسی کنید، زیرا آن عمل تبدیل خودکار را انجام خواهد داد. اطلاعات بیشتر در سند N4190 موجود است. همچنین موارد مرتبط دیگری با سند N4190 وجود دارند که در کتابخانه خذف شده اند مانند: unary_function/binary_function ptr_fun() mem_fun()/mem_fun_ref() bind1st()/bind2nd() random_shuffle قوانین جدید خودکار برای Direct-List-Initialization از سی پلاس پلاس ۱۱ به اینور که ما یک مشکل بزرگی در این رابطه داشتیم: auto x { 1 }; از initializer_list اینطور نتیجهگیری شده است. با استاندارد جدید، ما میتوانیم این مشکل را حل کنیم. بنابراین آن میتواند به عنوان نوع int که اکثر مردم تصور میکنند شناسایی شود. برای اینکه این اتفاق بیافتد، ما نیاز داریم که دو روش تخصیص مقدار اولیه را درک کنیم: کپی و مستقیم. auto x = foo(); // copy-initialization auto x{foo}; // direct-initialization, initializes an // initializer_list (until C++17) int x = foo(); // copy-initialization int x{foo}; // direct-initialization برای مقدار دهی اولیه، سیپلاسپلاس ۱۷ قوانین جدیدی را معرفی میکند: For a braced-init-list with only a single element, auto deduction will deduce from that entry; For a braced-init-list with more than one element, auto deduction will be ill-formed. برای مثال: auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int> auto x2 = { 1, 2.0 }; // error: cannot deduce element type auto x3{ 1, 2 }; // error: not a single element auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int> auto x5{ 3 }; // decltype(x5) is int جزئیات بیشتر را در سند N3922 میتوانید مشاهده کنید. همچنین جزئیات در رابطه با فهرست خودکار موجود هستند که توسط جناب آقای Ville Voutilainen اشاره شده است. این اضافات در سیپلاسپلاس از زمان MSVC 14.0، GCC 5.0 و Clang 3.8 کار میکنند. گزینه static_assert بدون هیچ نوع پیغامی این واضح است که، این به شما این امکان را می دهد که فقط بدون داشتن گذراندن پیام، نسخه دارای پیغام در دسترس خواهد بود. این سازگاری با سایر موارد مانند BOOST_STATIC_ASSERT وجود دارد. static_assert(std::is_arithmetic_v<T>, "T must be arithmetic"); static_assert(std::is_arithmetic_v<T>); // no message needed since C++17 جزئیات بیشتر در سند N3928 در دسترس است. پشتیبانی شده در MSVC 2017 ٬ GCC 6.0 و Clang 2.5. انواع مختلف شروع و پایان در محدوده حلقه از سیپلاسپلاس ۱۱ به بعد، محدوده مبتنی بر حلقه ها به صورت داخلی تعریف شده است: { auto && __range = for-range-initializer; for ( auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } } همانطور که میبینید، __begin و __end دارای نوع مشابه هستند. این ممکن است باعث مشکلاتی شود. برای مثال زمانی که شما چیزی شبیه یک نگهبان (محافظ) که از نوع داده دیگری است را داشته باشید مشکل ساز خواهد بود. در سیپلاسپلاس ۱۷ آن به صورت زیر تغییر کرده است: { auto && __range = for-range-initializer; auto __begin = begin-expr; auto __end = end-expr; for ( ; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } } انواع __begin و __end ممکن است متفاوت باشد چرا که فقط اپراتور مقایسه مورد نیاز است. این تغییر کلی باعث میشود که این ویژگی تجربه بیشتری را در این زمینه برای کاربران ارائه دهند. جزئیات بیشتر در P0184R0، پشتیبانی شده در MSVC 2017 ،GCC 6.0 و Clang 3.6.
-
1 امتیاز
نگارش ۱.۳.۸
2,331 دریافت
دنیای خود را چگونه با کیوت بسازیم!؟ با توجه به توسعهٔ روزافزون فناوری، دنیای نرمافزاری همگام با آن با سرعت بسیار زیادی در حال پیشرفت و توسعه است. ما برای رسیدن به این مسیر باید به فکر تولید و توسعهٔ محصول با کیفیت همراه با اقدامات کلیدی باشیم تا این محصول هماهنگ با استانداردهای جهانی باشد. برای این امر نیاز است تا این استانداردها را بررسی و در درون پروژههای خود مورد استفاده قرار دهیم. کیوت به عنوان یک چهارچوب قدرتمند یکی از بهترین و پیشتازترین ابزارهای موجود در دنیای برنامهنویسی است که با تمرکز بر روی مباحث تولید محصولی اساساً بر پایهٔ تجربهکاربری و رابطکاربریِ پیشرفته همراه با پشتیبانی از قدرتمندترین زبان برنامهنویسی، نتیجهای مطلوب را در مسیر توسعهٔ محصول نرمافزاری شما فراهم میکند. توجه داشته باشید برنامهنویسی صرفاً نوشتن کد منطقی و برقراری ارتباط با دادهها و حل مسائل مربوط به آن نیست! علاوه بر حل مشکل، برقراری ارتباط با احساسات کاربر و ایجاد یک تجربه و تعامل خوب بسیار مهم است. باید توجه داشت که زمان، هزینه، سرعت و کیفیت همه باهم مهم هستند و برای به حداکثر رساندن درجه کیفیت هر یک از این مولفهها باید از بهترین روشهای ممکن استفاده کرد که شامل مواردی همچون چند-سکویی، ابری، تجربهکاربری، رابطکاربری، رابطهای برنامهنویسی، کتابخانهها و غیره... میباشند و برای رسیدن به آنها کافی است یک زبان مهم و پایه همراه با چند زبان فرعی و فناوریهای مرتبط با یکدیگر را به عنوان ابزار در اختیار داشته باشیم. آخرین اعتبار تخفیفات ویژه به مناسبتهای اخیر به پایان رسیده است. نکتهٔ بسیار مهم: این کتاب به صورت رسمی در کتابخانهٔ ملی ثبت شده است، بنابراین هرگونه چاپ، تکثیر و به اشتراکگذاری این کتاب پیگیرد قانونی دارد. توجه: دریافت نسخههای بهروزرسانی شده تنها از این صفحه برای کسانی که حداقل یک بار آن را تهیه کردهاند امکانپذیر است. نوع این کتاب الکترونیکی است، بعد از پرداخت میتوانید بر روی دکمهٔ دریافت فایل در همین صفحه کلیک کرده و آن را دریافت نمایید. در صورتی که درگاه پرداختی با مشکل مواجه شده باشد، میتوانید به شماره کارت ۶۱۰۴۳۳۷۸۸۴۵۳۳۳۴۸ (بانک ملت) واریز و آن را به آدرس kambiz.ceo@gmail.com و یا شناسهٔ تلگرامی @Kambiz_Asadzadeh اطلاع دهید تا تأیید شود. از تاریخ ۲۶ آذر ۱۴۰۲ دریافت این کتاب بدون پرداخت هزینه توسط نویسنده تأیید میشود، شما میتوانید بعد از مطالعه هزینهٔ آن را بپردازید. در صورتی که از شما اطلاعات آدرس مکانی پرسیده شد، میتوانید آنها را وارد نکنید. * تمامی حقوق مادی و معنوی این کتاب متعلق به مولف و ناشر مولف (کامبیز اسدزاده) میباشد و هرگونه کپی برداری از آن پیگرد قانونی خواهد داشت. توجه : در داشتن هر گونه انتقاد و پیشنهاد در رابطه با این کتاب با آدرس شخصی نویسنده (kambiz.ceo@gmail.com) مکاتبه نمایید. نکته : این کتاب در روزهای خاص ممکن است شامل تخفیف قرار بگیرد. نکته دوم : کسانی که این کتاب را یک بار خریداری میکنند نسخهٔ بهروزرسانی شده آن را به صورت رایگان میتوانند دریافت کنند. برخی از درخواستها در کتاب مقدماتی به صورت زیر بودند: آموزش پیشرفته در رابطه با QML و آشنایی با آن آموزش برقراری ارتباط بین ++C و QML به صورت بکاند و فرانتاند آموزش کار با کنترلها و نحوهٔ سفارشی سازی پروژه آموزش برقراری ارتباط با پایگاه داده و فناوری های مرتبط با آن آموزش نحوهٔ پیکربندی کیتها، کامپایلر و ... آموزش نحوه توسعه برنامه بر روی بسترهای مختلف از جمله اندروید، آیاواس و ... و درخواستهای دیگر... بنابراین بر اساس این درخواستها و محتوایی که نیاز می باشد بعد از جلد مقدماتی با آنها آشنا باشید را در این نسخه فراهم کرده ایم. نکته از نظر من در رابطه با محتوا: کتابخانه کیوت شامل مباحث بسیار زیادی است که میتوان از هزاران صفحه محتوای آموزشی تولید کرد. اما در این محتوای آموزشی من تنها به مواردی اشاره کردهام که لازمهٔ کار هستند و در پروژهها میبایست اطلاعات لازم در رابطه با آنها داشته باشید. سرفصل ها و محتوا چه چیزهایی هستند؟ محتوای کتاب طبق آخرین استاندارد کتابخانه بر پایه نسخه ۵.۸ به بالا میباشد. محتوای آن به نسخه ۵.۹ و حتی ۵.۱۳ بهروزرسانی شده است. همچنین ویژگی های و موارد مهمی که در نسخه ۵.۹ و ۵.۱۰ موجود هستند در این کتاب به آنها اشاره شده است. سر فصلهای نهایی و تایید شده کتاب: فصل اول مقدمه بر زبان ++C برخی از قابلیتها ساختار برنامه در ++C کتابخانهها فرق بین C و ++C ویژگیهای معرفی شده در ++C ویرایشهای ۱۱ ٬ ۱۴ و ۱۷ کامپایلرهای ++C و وضعیت آنها ساختار اسناد ++C در پروژه کاربرد این زبان در کجاست؟ استانداردهای زبان مقدمه کیوت (Qt) معرفی کیوت (Qt) ۵.۹ آشنایی با محیط توسعه، نصب و راه اندازی همراه با پیکربندی کیت (Kit) در آن نصب و راه اندازی محیط Qt پیکربندی کیتها در macOS پیکربندی کیتها در Linux پیکربندی کیتها در Windows معرفی محیط توسعه کیوت کرِیتور (Qt Creator) نسخه 4 پیکربندی و تنظیمات مربوط به ساخت برای پلتفرمهای مختلف معرفی مجوز های Qt و نحوه استفاده از مناسبترین مجوز لوگوهای نشانگر ساخته شده با Qt پشتیبانی از انواع پلتفرمها پشتیبانی از انواع معماری ها شرایط و قوانین لازم جهت انتشار اپلیکیشن در فروشگاه iTunes یا همان (Apple Store) شرایط و قوانین لازم جهت انتشار اپلیکیشن در فروشگاهWindows Store شرایط و قوانین لازم جهت انتشار اپلیکیشن در فروشگاه Google Play شرایط و قوانین اختصاصی برنامه تحت Qt جهت انتشار و پذیرش در فروشگاه های مرتبط فصل دوم معرفی فناوری Qt Quick ویرایش 2 معرفی زبان کیو اِم اِل (QML) ویرایش 2 آشنایی با سبک - سینتَکس (Syntax) زبان QML روش اعلام یا اظهار یک شیء در QML اشیاء فرزند (Child-Object) در QML سبک و روش اعمال اظهار نظر (Comment) در QML صفت های اشیاء در QML پشتیبانی از جاوا اسکریپت (JavaScript) و ترکیب آن با QML روش استفاده از جاوا اسکریپت در سند QML روش های ترکیب ++C و استفاده از آن در سند QML فصل سوم معرفی انواع پروژه ها تحت فناوری کیوت کوئیک (Qt Quick) معرفی پروژه از نوع Qt Widget Application معرفی پروژه از نوع Qt Console Application معرفی پروژه از نوع Qt Quick Application معرفی پروژه از نوع Qt Quick Controls 2 Application معرفی پروژه از نوع Qt Quick Controls Application معرفی پروژه از نوع Qt Quick Canvas 3D Application معرفی پروژه از نوع Qt Quick Labs Controls Application آغاز ایجاد پروژه تحت C++ و Qt Quick ساده ترین برنامه معرفی کلاس QGuiApplication معرفی کلاس QQmlApplicationEngine معرفی کلاس QCoreApplication معرفی تابع exect در پروژه فصل چهارم انواع کنترل ها، منو ها و دیگر آبجکت ها معرفی انواع QML پایه در فناوری Qt Quick نوع date نوع color نوع font نوع matrix4x4 نوع point نوع quaternion نوع rect نوع size نوع vector2d نوع vector3d نوع vector4d معرفی انواع اشیاء QML در فناوری Qt Quick معرفی Accessible معرفی AnchorAnimation معرفی AnchorChanges معرفی AnchorImage معرفی AnimatedSprite معرفی Animation معرفی AnimationController معرفی Animator معرفی Behavior معرفی BorderImage معرفی Contex2D معرفی Canvas معرفی CanvasGradient معرفی CanvasImageData معرفی CanvasPixelArray معرفی CanvasColorAnimation معرفی Column معرفی DoubleValidator معرفی Drag معرفی DragEvent معرفی DropArea معرفی EnterKey معرفی Flickable معرفی Flipable معرفی Flow معرفی FocusScope معرفی FontLoader معرفی FontMeteric معرفی Gradient معرفی GridMesh معرفی GridView معرفی Image معرفی IntValidator معرفی Item معرفی ItemGraResult معرفی KeyEvent معرفی KeyNavigation معرفی Keys معرفی LayoutMirror معرفی ListView معرفی Loader معرفی MouseArea معرفی MouseEvent معرفی MultiPointTouchArea معرفی NumberAnimation معرفی OpacityAnimator معرفی ParallelAnimation معرفی GraphicInfo معرفی ParentAnimation معرفی ParentChange معرفی Path معرفی PathAnimation معرفی PathView معرفی PauseAnimation معرفی PropertyAction معرفی PropertyChanges معرفی Rectangle معرفی RegExpValidator معرفی Repeater معرفی Rotation معرفی RotationAnimation معرفی RotationAnimator معرفی Row معرفی Scale معرفی ScaleAnimator معرفی SecuentialAnimation معرفی ShaderEffect معرفی ShaderEffectSource معرفی Shortcut معرفی SmoothedAnimation معرفی SpringAnimation فصل پنجم معرفی انواع کنترل های 2 Qt Quick Controls کنترل AbstractButton کنترل ApplicationWindow کنترل BusyIndicator کنترل Button کنترل ButtonGroup کنترل CheckBox کنترل CheckDelegate کنترل ComboBox کنترل Container کنترل Control کنترل Dial کنترل Drawer کنترل Frame کنترل GroupBox کنترل ItemDelegate کنترل Label کنترل Menu کنترل MenuItem کنترل Page کنترل PageIndicator کنترل Pane کنترل Popup کنترل ProgressBar کنترل RadioButton کنترل RadioDelegate کنترل RangeSlider کنترل ScrollBar کنترل ScrollIndigator کنترل Slider کنترل SprinBox کنترل StackView کنترل SwipeDelegate کنترل SwipeView کنترل Switch کنترل SwitchDelegate کنترل TabBar کنترل TabButton کنترل TextArea کنترل TextField کنترل ToolBar کنترل ToolButton کنترل ToolTip کنترل Thumbler فصل ششم معرفی Qt Quick Dialog (دیالوگ های انتخاب رنگ، فایل، فونت و پیغام) معرفی Color Dialog معرفی Font Dialog معرفی File Dialog معرفی Message Dialog معرفی Qt Quick Layouts معرفی Column Layout معرفی Grid Layout معرفی Row Layout معرفی Stack Layout معرفی Qt Quick Control Styles (سبک و استایل نویسی کنترل ها – سفارشی سازی) واکنش گرایی و پاسخ دهی محتوای وب در اپلیکیشن با Qt WebEngine محتوای چند رسانه ای در کیوت QMultimedia محتوای چند رسانه ای در کیوت QMultimedia پخش صوت ظبط صدا در فایل پخش ویدیو کار با دوربین فصل هفتم معرفی و پیکربندی کار با بانک اطلاعاتی (دیتابیس) کار با بانک اطلاعاتی و ارتباط آن بین C++ و QML معرفی و کار با XML معرفی و کار با JSON معرفی و کار با QSetting سفارشی سازی فایل .pro پروژه فصل هشتم مقایسه انواع حالت های کامپایل Debug و Release نحوه افزودن دیگر کتابخانه های C++ در محیط Qt Creator و استفاده همراه با کتابخانه Qt فرق بین کامپایل استاتیک و داینامیک نحوه خروجی گرفتن / گسترش (Deployment) در Qt پیکربندی و انتشار برنامه در پلتفرم ویندوز (Windows) پیکربندی و انتشار برنامه در پلتفرم مک (macOS) پیکربندی و انتشار برنامه در پلتفرم لینوکس (Linux) پیکربندی و انتشار برنامه در پلتفرمهای iPhone و iPad (iOS) پیکربندی و انتشار برنامه در پلتفرم اندروید (Android) معرفی ابزار کیوبس (QBS) به روز رسانی کیوت بدون دریافت فایل نصبی آفلاین اهداف و چشمانداز فنی کیوت ۶ پیشنهادات و ملاحظات در عملکرد و کارآیی (جدید)رایگان
-
1 امتیاز
نگارش 5.0
977 دریافت
هدف از این آموزشها آشنایی با امکاناتی که در Qt میتوان استفاده کرد میباشد، که شامل کدنویسی کمتر، خروجی و طرح های بیشتر و در نهایت استفاده در پلتفرمهای مورد مختلف است. لذا جهت بهرهمندی از این کتابخانه ما با در نظر گرفتن اینکه علاقهمندان با زبان ++C آشنایی لازم را دارند منتشر کردهایم. بنابراین در صورتی که علاقهمندان اطلاعات کافی در رابطه با خود زبان ندارند پیشنهاد میکنیم ابتدا اقدام به تهیه و مطالعه آموزشهای لازم در ++C نمایند که برخی از لینکهای رسمی و استاندارد آن را در زیر اعلام نمودهایم. نوع این کتاب الکترونیکی است، بعد از پرداخت میتوانید بر روی دکمهٔ دریافت فایل در همین صفحه کلیک کرده و آن را دریافت نمایید. در صورتی که درگاه پرداختی با مشکل مواجه شده باشد، میتوانید به شماره کارت ۶۱۰۴۳۳۷۸۸۴۵۳۳۳۴۸ (بانک ملت) واریز و آن را به آدرس kambiz.ceo@gmail.com و یا شناسهٔ تلگرامی @Kambiz_Asadzadeh اطلاع دهید تا تأیید شود. از تاریخ ۲۶ آذر ۱۴۰۲ دریافت این کتاب بدون پرداخت هزینه توسط نویسنده تأیید میشود، شما میتوانید بعد از مطالعه هزینهٔ آن را بپردازید. عنوان این آموزش "برنامه نویسی ++C همراه با کتابخانه های Qt 5.12.x (سطح مقدماتی ویرایش ۵) میباشد که به صورت زیر فهرست بندی شده است: فصل اول مقدمه کتابخانه Qt قابلیت ها در طراحی فناوری Qt Quick و QML نسخه های کیوت مجوز های موجود در این کتابخانه محیط های توسعه کیوت ویژگی های کیوت پشتیبانی از انواع سیستم عامل ها نصب و پیکربندی Qt فصل دوم انواه پروژه و ایجاد آن انواع پروژه ها ایجاد پروژه فصل سوم ساده ترین برنامه معرفی و کار با Signal و Slot ها و Event ها معرفی و کار با نمایش Windows معرفی و کار با لایه ها زبانه ها و بدنه های در طراحی معرفی و کار با قابلیت های HTML و CSS در طراحی فصل چهارم معرفی و کار با لایه های افقی و عمودی معرفی و کار با لایه های Grid در طراحی فرم معرفی و کار با جدا کننده ها Splitter فصل پنجم معرفی و کار با دایرکتوری ها معرفی و کار با فایل ها / خواندن و نوشتن در آن ها فصل ششم معرفی و کار با برچسب ها Label معرفی و کار با دکمه ها Button معرفی و کار با کنترل ورودی LineEdit معرفی و کار با چک باکس CheckBox معرفی و کار با RadioButton معرفی و کار با Combobox معرفی و کار با لیست ها / ListWidget معرفی و کار با لیست های درختی / TreeWidget معرفی و کار با Action ها معرفی و کار با Slider و Progress ها معرفی و کار با Statusbar در فرم فصل هفتم معرفی و کار با MessageBox معرفی و کار با Timer معرفی و کار با Thread ها فصل هشتم معرفی و کار با Map معرفی و کار با Hash معرفی و کار با QStringList لیست رشته ای فصل نهم معرفی و کار با الگوریتم های معرفی و کار شبکه / دانلود فایل بر اساس پروتکل های HTTP و FTP معرفی و کار با باینری و سریالیز کردن آبجکت ها معرفی و کار با TextStream ها فصل دهم مقایسه انواع حالت های کامپایل در Qt نحوه افزودن دیگر کتابخانه های C++ در محیط Qt Creator و استفاده همراه با کتابخانه Qt نحوه خروجی گرفتن / گسترش (Deployment) در Qt مقایسه و پیکربندی دو موتور قدرتمند OpenGL و ANGLE در پروژه درایور دیتابیس هایی که تحت این کتابخانه پشتیبانی میشوند ساخت راهانداز دیتابیس در پلتفرمهای Linux، macOS و Windows حق نشر کتاب و اهداف در نسخهٔ بعدی کتاب توجه : در داشتن هر گونه انتقاد و پیشنهاد در رابطه با این کتاب با آدرس شخصی نویسنده (kambiz.ceo@gmail.com) مکاتبه نمایید. نکته دوم : کسانی که این کتاب را یک بار خریداری میکنند نسخهٔ به روز رسانی شده آن را به صورت رایگان میتوانند دریافت کنند.رایگان
-
1 امتیاز
-
1 امتیازاحساس افسردگی و اسکلی کردم آخه با وجود اینکه تا بحال روی دو تا پروژه کار کردم و شاغلم فهمیدم زیادی سریع فکر کردم دیگه همه چیز دانم و باید کار را شروع کنم حداقل نصف چیزایی که گفتی را بلد نیستم (البته خوشحالم که هنوز راه زیادی برای یادگیری در پیش دارم راه خیلی زیاد ...)
-
1 امتیازجزئیات، بهروز رسانیها و ویژگیهای C++20 معرفی و نمونه کدهای کلاس std::span کلاس std::span یک کلاس در C++20 است که برای نشان دادن (نمایش ظاهری) یک محدوده دنبالهای از اشیاء پیوسته بکار میرود. الگوی کلاس span یک شیء را توصیف میکند که میتواند به یک دنباله متوالی از اشیاء با اولین عنصر دنباله در موقعیت صفر ارجاع دهد. یک span میتواند دارای دامنهی استاتیک باشد، در این صورت تعداد عناصر در دنباله در زمان کامپایل مشخص است و در نوع خودشان رمزگذاری شدهاند و یا دامنهی داینامیک دارد. اگر یک span دارای دامنهٔ داینامیک باشد، به طور معمول، پیادهسازی آن شامل دو عضو است: یک اشارهگر به T و یک اندازه است. یک span با دامنهٔ استاتیک ممکن است فقط یک عضو داشته باشد: یک اشارهگر به T. template< class T, std::size_t Extent = std::dynamic_extent > class span; برای استفاده از کلاس std::span، باید ابتدا کتابخانه <span> را به کدتان اضافه کنید. سپس برای ایجاد یک شیء از این کلاس، میتوانید از یک اشارهگر به شروع دنباله و طول آن استفاده کنید. برای مثال: #include <span> #include <iostream> int main() { int arr[] = {1, 2, 3, 4, 5}; std::span<int> mySpan(arr, 5); for (int i : mySpan) { std::cout << i << " "; } return 0; } در این مثال، یک آرایه از نوع int با ۵ عضو تعریف شده و سپس یک شیء از کلاس std::span با استفاده از این آرایه و طول آن ایجاد میشود. سپس با استفاده از حلقه for، اعضای دنباله در خروجی چاپ میشوند. استفاده از std::span میتواند در کدهایی که بر روی دادههای چند بعدی یا برای دادههایی که آنها نمیتوانند با طول ثابت در داخل یک آرایه شبیهسازی شوند، مفید باشد. همچنین، با استفاده از std::span میتوان با مراجعه به همه اعضای یک آرایه به صورت پویا از زمان اجرا، از یک پیادهسازی معمولی با تراکم حافظه کمتر استفاده کرد. همچنین استفاده از std::span برای پشتیبانی از روشهای پیشرفتهتر و بازبینی کدها مفید است. اینجا یک نمونه از استفاده از std::span در یک کد C++20 آورده شده است: #include <iostream> #include <span> int main() { int arr[] = {1, 2, 3, 4, 5}; std::span<int, 5> s(arr); // s refers to the whole array for (auto& elem : s) { // range-based for loop std::cout << elem << ' '; } std::cout << '\n'; std::span<int, 3> s2(arr + 1, 3); // s2 refers to {2, 3, 4} for (auto& elem : s2) { std::cout << elem << ' '; } std::cout << '\n'; } در این کد، یک آرایه از 5 عدد تعریف شده است. سپس با استفاده از std::span، دو نمونه برای این آرایه تعریف شده است. پس از آن ، با استفاده از حلقه for ، مقادیر در هر دو نمونه std::span به ترتیب چاپ شده و تفاوت بین آنها نیز نشان داده شده است. برخی از مزایای این کلاس به صورت زیر است: کد مطمئنتر: به دلیل استفاده از نمای مناسبی از ارثبری، این کلاس امکان بازنویسی کد و تجدید نظر در طراحی را فراهم میکند. کاربردهای متعدد: توانایی نشان دادن دادههای پیوسته با هر نوع، دنبالههای داخلی و خارجی، بردارها، ماتریسها و موارد دیگر، std::span را به یک وسیله کارآمد در برنامهنویسی ترکیبشدها و همزمانسازی دادهها تبدیل کرده است. عملکرد بهتر: به دلیل این که std::span یک کلاس ساده به همراه تعریف مجددی از iterator (https://en.cppreference.com/w/cpp/iterator) هاست، عملیاتی مانند خواندن، نوشتن و مرتب سازی دادهها، بسیار سریعتر از زیربرنامههای برنامه سازی بهینه شده است. پشتیبانی از تشخیص خطا: با استفاده از std::span، میتوان یک شیء معتبری ایجاد کرد که در آن تغییرات اندیس باید در محدوده معتبر واقع شود که باعث بهبود تشخیص خطا در کد میشود. اینجا یک نمونه کد ورودی با std::span برای محاسبه میانگین اعداد یک محدوده از داده هاست که توضیحات کد نیز در کد ذکر شده است: #include <iostream> #include <span> #include <algorithm> double average(std::span<int> ns) { if (ns.empty()) throw std::invalid_argument("empty span"); if (ns.size() > static_cast<size_t>(std::numeric_limits<int>::max())) throw std::invalid_argument("span size exceeds int max"); if (std::any_of(ns.begin(), ns.end(), [](const int& n) { return n < 0; })) throw std::invalid_argument("span contains negative values"); return static_cast<double>(std::accumulate(ns.begin(), ns.end(), 0)) / ns.size(); } int main() { int arr[] = { 1, 2, 3, 4, 5 }; std::span<int> span_arr(arr, 5); try { std::cout << average(span_arr) << '\n'; } catch(const std::exception& ex) { std::cerr << "Error: " << ex.what() << '\n'; } return 0; } در کد زیر، یک std::span از یک آرایه از اعداد پشت سر هم ایجاد شده است و سپس به عنوان ورودی به تابع calculate_mean() منتقل شده است. تابع calculate_mean() به صورت یک حلقه که به ازای عنصری که به عنوان ورودی دریافت می کند، محدوده داده ها را پیمایش می کند و میانگین اعداد را محاسبه می کند. با استفاده این تابع و تعریف یک آرایه از اعداد، برنامه قادر است میانگین اعداد را محاسبه کند. #include <iostream> #include <span> double calculate_mean(std::span<double> nums) { double sum = 0.0; for (auto num : nums) { sum += num; } return sum / static_cast<double>(nums.size()); } int main() { double nums[] = {2.0, 3.0, 5.0, 7.0, 11.0, 13.0}; std::span<double> nums_span(nums, std::size(nums)); double mean = calculate_mean(nums_span); std::cout << "mean = " << mean << std::endl; return 0; } کاربرد std::span در ورودی توابع یکی از استفاده های مهم std::span ، به عنوان ورودی تابع است. با استفاده از std::span به عنوان ورودی، می توان به سادگی یک محدوده از داده ها را به یک تابع انتقال داد و از انتقال داده های اضافی و همچنین رعایت روشن بودن کد استفاده کرد. با استفاده از std::span به عنوان ورودی تابع، عملیات از هر نوع می تواند مستقل از نوع داده های کانتینر باشد و به همین دلیل کد تمیز تر و بیشتر چند منظوره خواهد بود. #include <iostream> #include <span> double calculateAverage(std::span<double> nums) { double sum = 0; for (auto num : nums) { sum += num; } return (nums.size() > 0) ? sum / nums.size() : 0; } int main() { double data[] = {2.5, 3.8, 4.2, 1.7, 6.5}; double average = calculateAverage(data); std::cout << "Average: " << average << std::endl; return 0; } در این کد، تابع calculateAverage یک std::span از نوع double به عنوان ورودی دریافت می کند و با استفاده از آن، میانگین عناصر را محاسبه می کند. سپس در تابع main یک آرایه از اعداد اولیه تعریف شده است که به عنوان ورودی به تابع calculateAverage ارسال می شود و سپس میانگین محاسبه شده چاپ می شود. استفاده از std::span به خصوص زمانی مناسب است که به دنبال ارسال یک محدوده از داده ها به تابع هستیم، بدون آنکه نیاز به کپی کردن داده ها باشد. در این حالت، استفاده از std::span به جای استفاده از نشانگر به عنوان ورودی تابع، توصیه می شود. با استفاده از std::span، می توان محدوده ای از داده ها را مستقیماً به تابع انتقال داد و از کپی نشانگر آندونه و داده های مربوط به آن جلوگیری کرد و در عین حال، کد را شفاف تر و آسان تر قابل فهم نیز می کند. کاربرد std::span در کلاسها استفاده از std::span در کلاس ها، می تواند در طراحی کلاس هایی که بر روی داده هایی فیکسشده کار می کنند، مفید باشد. این کار به تشخیص و جلوگیری از خطرات مربوط به ارجاع به اشاره یا نشانگر اشاره که به محدوده ای خارج از داده های کلاس مستقر شده اند، کمک می کند. #include <span> class DataProcessor { private: std::span<const int> data; public: explicit DataProcessor(std::span<const int> d) : data(d) {} double calculateMean() const { double sum = 0.0; for (auto num : data) { sum += num; } return sum / static_cast<double>(data.size()); } }; همچنین، میتوان با تعریف تابعهایی که با std::span کار می کنند، از صرفه جویی در حجم کدها خود لذت برد. اینجا یک نمونه کد با استفاده از std::span در طراحی یک کلاس برای مدیریت یک آرایه با سایز ثابت است: #include <array> #include <span> template <typename T, std::size_t N> class FixedArray { public: FixedArray(std::array<T, N>& arr) : data(arr), memory(data) { } std::span<T, N> memory; private: std::array<T, N>& data; }; در این کد، FixedArray یک کلاس است که یک آرایه با سایز ثابت را مدیریت میکند. با استفاده از std::span، ما میتوانیم برای نگهداری دادهها از حافظهای استفاده کنیم که قبل تر allocated شده است (در اینجا دادهها از آرایه data استخراج شده و به صورت پویایی در memory نگهداری میشوند). به این ترتیب، ما از خطرات ارجاع به اشاره به محدودههای خارج از داده ها به دلیل دستکاری در آرایه، محافظت میکنیم.
-
1 امتیازعلیکم سلام، طبق این دو آموزش پیش برید. پیکربندی فریمورک کیوت برای پلتفرم اندروید پیکربندی و بهروز رسانی کیوت ۶.۴ برای اندروید ۱۳
-
1 امتیازسادهترین راه برای افزودن کد سفارشی به سایتهایی که بر پایهٔ وردپرس ساخته شدهاند، بدون شکستن کد آن چیست؟ زبان برنامهنویسیِ ++C یکی از محبوبترین زبانهای برنامهنویسی است. آخرین آمار نشان میدهد که این زبان با سرعت بسیار زیادی در حال توسعه و پوستاندازی است. این زبان، علیرغم اینکه بیش از 40 سال از عمرش میگذرد، همچنان زبان انتخابی برای بسیاری از برنامهنویسان در سراسر جهان است. برای بسیاری از موارد مانند برنامههای کاربردی دستکاری تصویر، بازیهای سه بعدی، شبیه سازیها، مرورگرهای وب و نرمافزارهای سازمانی استفاده میشود. دلیلش این است که سیپلاسپلاس در حال تکامل است، به انرژی سبز اهمیت میدهد و در عین حال کارآیی بسیار بالا و بهینهای دارد. از آنجایی که این زبان پیچیدهتر از سایر زبانهای برنامهنویسی است، یک کمیتهٔ فرعی از یک سازمان چند سطحی وظیفه استانداردسازی آن را بر عهده دارد. سیپلاسپلاس اکنون از یک مدل قطار پیروی میکند و هر سه سال یکبار نسخههای جدید دریافت میکند که در مورد استانداردهای جدید، اخیراً مقالاتی منتشر شده است. سیپلاسپلاس معمولاً برای توسعهٔ نرمافزار در مقیاس بزرگ استفاده میشود، اما میتوان از آن برای پروژههای توسعه وب نیز استفاده کرد. ممکن است تعجب کنید که چگونه از آن با وردپرس، یکی از محبوبترین سیستمهای مدیریت محتوا و سازندگان وب سایت امروزه استفاده کنید. در این باره قبلاً من مقالاتی را منتشر کردهام که به صورت زیر آمدهاند: در حالی که بسیاری از وب سایتها با استفاده از وردپرس به عنوان پایه ساخته میشوند، این لزوماً به این معنی نیست که اکوسیستم وردپرس تکامل یافته یا کامل است. به عنوان مثال، وردپرس تمرکز زیادی بر تجربهکاربران و نیازهای وبلاگ نویسان دارد، به همین دلیل است که بر چهار زبان HTML، CSS، جاوا اسکریپت و PHP متکی است و این بدان معناست که برای توسعهدهندگانی که میخواهند به طور کامل از قدرت آن استفاده کنند، محدودیتهایی وجود دارد. در حالی که افزونههایی مانند Custom Post Types برای گسترش عملکرد وردپرس وجود دارد و راههای زیادی برای افزودن قابلیتهای جدید بدون شروع از ابتدا وجود ندارد. همچنین، افزودن کد ++C به طور مستقیم به یک سایت وردپرس توصیه نمیشود زیرا به طور بالقوه میتواند آسیب پذیریهای امنیتی را ایجاد کند و وب سایت را خراب کند. با این حال، اگر نیاز خاصی به اجرای کد ++C در سایت وردپرس شما وجود دارد، در اینجا روشهایی که میتوانید آن را انجام دهید گفته شدهاست: شما می توانید یک برنامه یا کتابخانه مستقل ++C ایجاد کنید و سپس آن را از طریق وب API در معرض دید قرار دهید، که میتواند توسط وردپرس مصرف شود. بیایید نگاهی به مراحل کلی بیندازیم: کد ++C خود را بنویسید و آن را در یک برنامه یا کتابخانه مستقل کامپایل کنید. عملکرد برنامه یا کتابخانه ++C را از طریق وب API به نمایش بگذارید. شما میتوانید از یک کتابخانه به عنوان cpprestsdk برای ایجاد نقاط پایانی API استفاده کنید. برنامه یا کتابخانه ++C را بر روی یک سرور، یا در همان سرور سایت وردپرس خود یا در یک سرور جداگانه، مستقر کنید. در سایت وردپرس خود، از یک افزونه یا کد سفارشی برای درخواست HTTP به API و بازیابی نتایج استفاده کنید. شما میتوانید از کتابخانهای مانند cURL برای ارائه چنین درخواستهایی استفاده کنید. در صورت نیاز از نتایج بازیابی شده در سایت وردپرس خود استفاده کنید. راه دیگر برای افزودن قابلیت ++C به سایت وردپرس استفاده از افزونهای است که به شما امکان میدهد کد ++C را مستقیماً در صفحات یا پستهای وردپرس جاسازی کنید. مراحل بسته به افزونهای که استفاده میکنید متفاوت است، اما در اینجا چند مرحله کلی وجود دارد که میتواند کمک کند. افزونهای را که از کد ++C پشتیبانی میکند را در سایت وردپرس خود نصب کنید. یک صفحه یا پست جدید در وردپرس ایجاد کنید و کد کوتاه [cpp] را به قسمت محتوا اضافه کنید. در کد از نوع برچسبِ [cpp]، کد ++C خود را اضافه کنید. صفحه یا پست را منتشر کنید و آن را مشاهده کنید تا کد جاسازی شده ++C را در عمل ببینید. مجدداً توجه داشته باشید که افزودن کد ++C به طور مستقیم به یک صفحه یا پست میتواند خطرناک باشد. مهم است که پیادهسازی خود را به طور کامل آزمایش کنید تا مطمئن شوید که ایمن و قابل اعتماد است. از هر روشی که استفاده میکنید، به یک پایه محکم در سیپلاسپلاس و مهارتهای یکپارچه سازی وردپرس نیاز دارد. وقتی صحبت از وردپرس به میان میآید، شاید بهتر باشد از زبانی مانند PHP استفاده کنید. اگر میخواهید دربارهٔ ++C و نحوهٔ به حداکثر رساندن آن برای پروژهتان بیشتر بدانید، میتوانید به آموزههای مربوط به سیپلاسپلاس در این سایت را بررسی کنید یا کتابهای پیشنهادی در بخش معرفی زبان را بخوانید. فراموش نکنید که سیپلاسپلاس یک زبان جذاب و همیشه در حال تکامل است و افزودن آن به مجموعه مهارتهای شما سودمند است.
-
1 امتیازبا سلام، با توجه به گزارش آنتونی پولوخین که یکی از اعضای کمیتهٔ استانداردسازی WG21 (سازمانی که توسعهٔ زبان برنامهنویسی سیپلاسپلاس را کنترل میکند). این کمیته سه بار در هر سال، هر بار در یک شهر جدید در سراسر جهان جلسه برگزار میکند. در طول این جلسات، پیشنهاداتی برای تغییر در زبان در نظر گرفته میشود. همچنین به توسعهدهندههای محلی سی++ کمک میکنند تا پیشنهادات خود را ارائه کنند. خلاصهای از جلسهٔ ماه جولای با هدف نهایی شدن استاندارد ۲۳ که نشان میهد پیشرفت بزرگی به عنوان ویژگیهای جدید استاندارد ۲۳ وجود دارد ارائه شده است: فهرست برخی از ویژگیها به صورت زیر آمدهاست: std:mdspan std:flat_map std:flat_set freestanding std:print("Hello {}", "world") formatted ranges output constexpr for bitset, to_chars/from_chars std::string::substr() && import std; std::start_lifetime_as static operator() [[assume(x > 0)]] 16- and 128-bit floats std::generator و البته ویژگیهای بسیار بیشتر از این. ویژگی std::mdspan از زمان اتخاذ عملگر opertator[] چند بعدی در آخرین جلسه، معرفیstd::mdspan به عنوان یک ویژگی سادهتر مطرح شده است و نتیجهٔ یک آرایهٔ چند بعدی غیر مالک به صورت زیر است: using Extents = std::extents<std::size_t, 42,="" 32,="" 64="">; double buffer[ Extents::static_extent(0) * Extents::static_extent(1) * Extents::static_extent(2) ]; std::mdspan<double, Extents=""> A{ buffer }; assert( 3 == A.rank() ); assert( 42 == A.extent(0) ); assert( 32 == A.extent(1) ); assert( 64 == A.extent(2) ); assert( A.size() == A.extent(0) * A.extent(1) * A.extent(2) ); assert( &A(0,0,0) == buffer ); این ویژگی حتی میتواند با سایر زبانهای برنامهنویسی خارج از جعبه کار کند. به عنوان مثال، در پارامتر الگوی سوم خود، std::mdspan میتواند یکی از چندین کلاس طرح بندی از پیش تعریف شده را بگیرد: نوعstd::layout_right: سبک چیدمان برای C یا ++C، سطرها دارای شاخص صفر هستند. نوعstd::layout_left: سبک چیدمان برای Fortran یا Matlab، ستونها دارای شاخص صفر هستند. شما می توانید تمام جزئیات را در سند P0009 بیابید. نویسندگان قول دادهاند که در آینده نزدیک نمونههای زیادی از std:mdspan جدید ارائه کنند. ویژگی std::flat_map و std::flat_set نگهدارندههای شگفتانگیز flat_* از کتابخانهٔ بوست، دیگر در استاندارد اصلی سی++ در دسترس هستند. این خاصیتها در کار با دادههای کم بسیار پرکاربرد هستند. در زیر ساختها، ظروف flat دادهها را در یک آرایه مرتب شده ذخیرهسازی میکنند که به طور قابل توجهی تخصیص حافظهٔ پویا را کاهش داده و موقعیت دادهها را بهبود میبخشد. علیرغم پیچیدگی جستجوی O(log N) و پیچیدگی درجO(N) در بدترین حالت، ظروف مسطح هنگام کار با مقدار کمی از عناصر بهتر از std:unordered_map عمل میکنند. در واقع، در طی فرآیند استانداردسازی، ظروف flat_* به عنوان آداپتور ساخته شدهاند. به این ترتیب، برنامهنویسان میتوانند از نگهدارندههای خود برای پیادهسازی اساسی استفاده کنند: template <std::size_t N> using MyMap = std::flat_map< std::string, int, std::less<>, mylib::stack_vector<std::string, N>, mylib::stack_vector<int, N> >; static MyMap<3> kCoolestyMapping = { {"C", -200}, {"userver", -273}, {"C++", -273}, }; assert( kCoolestyMapping["userver"] == -273 ); const auto& keys = kCoolestyMapping.keys(); // Inspired by Python :) assert( keys.back() == "userver" ); یک نکتهٔ جالب این است که استاندارد STL برخلاف پیادهسازی Boost، کلیدها و مقادیر را در نگهدارندهها جداگانه ذخیره میکند. این مکانِ کلیدیِ بهبود یافته، جستجوی ظرفِ flat را سریعتر میکند. رابط کاملstd::flat_set در سند P1222 توضیح داده شده است، در حالی که شرح رابط std:flat_map در سند P0429 موجود است. مستقل (Freestanding) استاندارد ++C میگوید که امکان پیادهسازی کتابخانهٔ استاندارد به صورت میزبان (hosted) یا مستقل (freestanding) وجود دارد. پیادهسازی میزبان نیاز به پشتیبانی سیستمعامل دارد و باید تمام روشها و کلاسها را از کتابخانهٔ استاندارد پیادهسازی کند. مستقل (freestanding) میتواند بدون سیستمعامل کار کند، سختافزار مهم نیست، و برخی از کلاسها و توابع را شامل نمیشود. تا همین اواخر، هیچ توضیحی برای ایستادن آزاد وجود نداشت و سازندگان سختافزارهای مختلف بخشهای مختلفی از کتابخانهٔ استاندارد را ارائه میکردند. این کارِ پورت کردن کد را سختتر کرد و محبوبیت ++C را در محیطهای تعبیهشده (امبدها) تضعیف کرد. بنابراین، زمان تغییر آن فرا رسیده است! سند P1642 مشخص کرده است که کدام بخش از کتابخانهٔ استاندارد برای freestanding اجباری است. ویژگی std::print روشهایی از کتابخانهء محبوب fmt در C++20 اضافه شد. این کتابخانه آنقدر راحت و سریع بود که برنامهنویسان شروع به استفاده از آن کرده و تقریباً در همهجای کد خود به کار بردهاند، از جمله برای خروجی قالببندی شده: std::cout << std::format(“Hello, {}! You have {} mails”, username, email_count); اما کدی مانند آن به دلایل زیر کامل نیست: تخصیص پویا اضافی. نیاز به std::cout جهت قالببندی خطوط از قبل قالب بندی شده. عدم پشتیبانی از یونیکد. کدی که اندازهٔ فایل باینری حاصل را افزایش میدهد. ظاهری نه چندان جذاب. بنابراین، تمام این مشکلات با اضافه کردن متدهایstd::print حل شد: std::print(“سلام, {}! به جامعهٔ {} خوش آمدید!”, name, community); میتوانید جزئیات، معیارها و گزینههای استفاده ازstd::print باFILE* و استریمها را در سند P2093 بیابید. خروجی قالببندی شده محدودههای مقدار به لطف سند P2286 و، std::format (و std::print) اکنون میتوانند محدودههایی از مقادیر را بدون در نظر گرفتن اینکه در یک ظرف هستند یا توسط std::ranges::views::* ارائه شدهاند خروجی بگیرند. std::print("{}", std::vector<int>{1, 2, 3}); // Output: [1, 2, 3] std::print("{}", std::set<int>{1, 2, 3}); // Output: {1, 2, 3} std::print("{}", std::pair{42, 16}); // Output: (42, 16) std::vector v1 = {1, 2}; std::vector v2 = {'a', 'b', 'c'}; auto val = std::format("{}", std::views::zip(v1, v2)); // [(1, 'a'), (2, 'b')] ویژگی constexpr اخبار تجزیه و تحلیل عالی برای توسعهدهندگانی که با کتابخانههای مختلف کار میکنند وجود دارد: خاصیتهایstd::to_chars/std::from_chars اکنون میتوانند در مرحله کامپایل برای تبدیل مقادیر صحیح از متن به باینری استفاده شوند. این نیز باید هنگام توسعه DSL مفید باشد. به نظر میرسد توسعهدهندههای روسی Yandex Go (به نقل از عضو کمیته) قصد دارند از آن در چارچوب کاربر برای بررسی پرس و جوهای SQL در مرحله کامپایل استفاده کنند. گزینهٔ std::bitset نیز تبدیل به constexpr شده است، بنابراین کار با بیتها در مرحلهٔ کامپایل اکنون بسیار آسانتر از قبل است. دانیل گوچاروف روی std::bitset در سند P2417 کار کرد و الکساندر کارائف در سند std::to_chars/std::from_chars P2291 به او پیوست. با تشکر فراوان از آنها برای این کار خوب انجام شده! ویژگی import std; با توجه به اینکه، اولین ماژول کامل(تمامعیار) به کتابخانهٔ استاندارد (STL) اضافه شد. اکنون میتوان کل کتابخانه را با یک خط بر سند وارد کرد: import std;. اگر کل ماژول کتابخانهٔ استاندارد به جای گنجاندن فایلهای هدر وارد شود، ساختها میتوانند تا ۱۱ برابر (گاهی اوقات حتی ۴۰ بار!) سریعتر شوند. میتوانید بنچمارک ها را در P2412 مشاهده کنید. اگر به ترکیب ++C و C و همچنین استفاده از توابع C از فضای نام جهانی عادت دارید، ماژول std.compat برای شما مناسب است. وارد کردن آن همهٔ توابع فایلهای سرآیند C مانند ::fopen و ::isblank و همچنین محتویات کتابخانهٔ استاندارد را در اختیار شما قرار میدهد. با وجود همهٔ اینها، سند P2465 که ماژولهای جدید را پوشش میدهد، در واقع آنقدرها هم طولانی نیست. ویژگی std::start_lifetime_as تیمور داملر و ریچارد اسمیت یک هدیهٔ فوقالعاده برای همهٔ توسعهدهندگانی که روی برنامههای تعبیه شده (امبد) و پربار کار میکنند گرد هم آوردهاند. اکنون تنها چیزی که برای کار کردن همه چیز نیاز دارید این است: struct ProtocolHeader { unsigned char version; unsigned char msg_type; unsigned char chunks_count; }; void ReceiveData(std::span<std::byte> data_from_net) { if (data_from_net.size() < sizeof(ProtocolHeader)) throw SomeException(); const auto* header = std::start_lifetime_as<ProtocolHeader>( data_from_net.data() ); switch (header->type) {> // ... } } به عبارت دیگر، میتوانید بافرهای مختلف را به ساختارها تبدیل کنید و با آنها بدون reinterpret_cast، کپی کردن دادهها یا خطر عملکرد برنامهتان کار کنید. همه چیز در سند P2590 شرح و مستند شده است. ویژگیهای شناورهای (اعشاری) 16 و 128 بیتی استاندارد ++C اکنون شامل std::float16_t، std::bfloat16_t، std::float128_t و نام مستعار برای اعداد موجود با ممیز شناور است: std::float32_t، std::float16_t. شناورهای 16 بیتی در هنگام کار با کارتهای ویدئویی یا یادگیری ماشین کمک میکنند. به عنوان مثال، float16.h میتواند از انواع جدید شناور کوتاه بهرهمند شود. شناورهای 128 بیتی برای محاسبات علمی شامل اعداد بزرگ بهترین هستند. سندِ P1467 ماکروها را برای بررسی پشتیبانی کامپایلر برای اعداد جدید توصیف میکند، و حتی خاصیتِ stdfloat.properties، در جدول مقایسه با توصیف اندازههای مانتیس و توان در بیتها وجود دارد. ویژگی std::generator زمانی که کروتینها در استاندارد C++20 پذیرفته شدند، ایده این بود که میتوان از آنها برای ایجاد «مولد» استفاده کرد: توابعی که وضعیت خود را بین تماسها به خاطر میآورد و مقادیر جدید را بر اساس آن حالت برمیگرداند. در استاندارد C++23 با اشاره به، std::generator به عنوان یک کلاس جدید یاد میشود که به شما امکان میدهد به راحتی ژنراتورهای خود را ایجاد کنید: std::generator<int> fib() { auto a = 0, b = 1; while (true) { co_yield std::exchange(a, std::exchange(b, a + b)); } } int answer_to_the_universe() { auto rng = fib() | std::views::drop(6) | std::views::take(3); return std::ranges::fold_left(std::move(rng), 0, std::plus{}); } در مثال فوق میتوانید ببینید که ژنراتورها با std::ranges چقدر خوب کار میکنند. std::generator کارآمد و ایمن است. کدی که به نظر میرسد یک پیوند معلق ایجاد میکند در واقع کاملاً معتبر است و هیچ مشکلی ایجاد نمیکند: std::generator<const std::string&=""> greeter() { std::size_t i = 0; while (true) { co_await promise::yield_value("hello" + std::to_string(++i)); // Everything is ok! } } میتوانید مثالها و توضیحاتی دربارهٔ نحوه کارکرد و استدلال پشت این رابط را در سند P2502 بیابید. سورپرایزهای دلپذیر کلاس string استاندارد برای متد substr() برای ارجاعات rvalue یک بازنگری اساسی (بهبود) دریافت کرده است: std::string::substr() &&. مانند مثال زیر: std::string StripSchema(std::string url) { if (url.starts_with("http://")) return std::move(url).substr(5); if (url.starts_with("https://")) return std::move(url).substr(6); return url; } این روش اکنون بدون تخصیص پویا اضافی کار میکند. اطلاعات بیشتر را میتوانید در سند P2438 بیابید. به لطف سند P1169، اکنون میتوانیدoperator() را ثابت اعلام کنید، که برای ایجاد CPO برای محدودهها در کتابخانه استاندارد عالی است: namespace detail { struct begin_cpo { template <typename T> requires is_array_v<remove_reference_t<T>> || member_begin<T> || adl_begin<T> static auto operator()(T&& val); }; void begin() = delete; // poison pill } // namespace detail namespace ranges { inline constexpr detail::begin_cpo begin{}; // ranges::begin(container) } // namespace ranges علاوه بر std::start_lifetime_as، تیمور داملر یک راهنمایی عالی برای بهینهساز ارائه کرد[[assume (x > 0)]]. اکنون میتوانید در مورد مقادیر احتمالی اعداد و سایر متغیرهای ثابت به کامپایلر نکاتی بدهید. برخی از مثالها و معیارها در سند P1774 کاهش پنج برابری در تعداد دستورالعملهای اسمبلی را نشان میدهند. این استاندارد همچنین دارای بسیاری از ویرایشهای جزئی، رفع اشکال و پیشرفتها بوده است، در اینجا منظور استاندارد ۲۳ است. در برخی مکانها، از سازندههای حرکتی (move constructors) به جای سازندههای کپی (copy constructors) استفاده شد (P2266). خوشبختانه برای توسعهدهندگان درایور، برخی از عملیات فرار دیگر منسوخ نمیشوند (P2327 با رفع اشکال در C++20). عملگر<=> کدهای قدیمی را کمتر میشکند (P2468)، کاراکترهای یونیکد اکنون میتوانند با نام استفاده شوند (P2071)، و کامپایلرها عموماً برای پشتیبانی از یونیکد (P2295) مورد نیاز هستند. الگوریتمهای جدید برای محدودهها (ranges::contains P2302, views::as_rvalue P2446, views::repeat P2474, views::stride P1899, و ranges::fold P2322) و std::format_string برای بررسیهای زمان کامپایل اضافه شد. std::format (P2508) و ماکروی #warning در (P2437). محدودهها (Ranges) یاد گرفتاند که چگونه با انواع فقط حرکت کار کنند (P2494). و در نهایت std::forward_like برای ارسال متغیرها بر اساس نوع متغیر دیگری اضافه شد (P2445). برای مدت طولانی، به نظر میرسید مهمترین نوآوری C++23 اضافه کردن std::stacktrace از RG21 بود، اگرچه در آخرین جلسه ویژگیهای مورد انتظار بسیاری اضافه شد. نوآوریهایی برای توسعهدهندگان تعبیه شده، شیمیدانان/فیزیکدانان/ریاضیدانان/...، توسعهدهندگان کتابخانههای یادگیری ماشین، و حتی توسعهدهندگانی که روی برنامههای کاربردی با بار بالا کار میکنند، وجود دارد.
-
1 امتیازسلام مجدد، بالاخره تونستم با راهنمایی شما مشکل رو حل کنم البته کدها رو به این شکل تغییر دادم (به عنوان مثال برای عمل جمع) BigInt result; result = previousVal + currentVal; ui->resultdisplay->setText(result.to_string().c_str()); و دستور زیر رو حذف کردم: //ui->resultdisplay->setText(ui->resultdisplay->text()+QString::number(currentVal)+"="+QString::number(previousVal + currentVal)); سپاس از شما
-
1 امتیاز
-
1 امتیازخیلی از شما ممنونم. بله درست میفرمایید، حتما تمام تلاشم رو میکنم تا اصولش رو یاد بگیرم.
-
1 امتیاز
-
1 امتیازسلام مهندس من راه حل این مورد و پیدا کردم ظاهرا به ورژن Qt Creator هم ربطی نداشته باید در بخش پلاگین نقشه قطعه زیر اضافه بشه : PluginParameter { name: "osm.mapping.providersrepository.disabled" value: "true" } PluginParameter { name: "osm.mapping.providersrepository.address" value: "http://maps-redirect.qt.io/osm/5.6/" } در ضمن بعد از اینکه این مورد و اضافه کردم و یک بار برنامه رو اجرا کردم و نقشه لود شد برای آزمایش این قطعه کد و حذف کردم ولی دوباره برنامه کار کرد. محض یادآوری نسخه Qt Creator 6.0.2 هستش و روی پلتفرم ویندوز 10 از راهنمایی های شما سپاسگذارم مهندس?
-
1 امتیازمتاسفانه زمان اجرای برنامه که قراره اطلاعات نقشه رو از osm بگیره یک ERORR به شکل زیر ظاهر میشه : qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed مطلب قابل قبولی پیدا نکردم متاسفانه
-
1 امتیازدر مورد اتصال به Api که خب مشخصه باید از کلاسهای شبکه استفاده کنید و به ساختار مشخصی مثل Restful وصل بشید. در مورد ساختِ خود Apiها و وبسرویسها هم باز میتونید سمت سرور با همین کلاسها وبسرویس رو ارائه بدین، معماری و قالب جیسان یا امثالش رو تولید کنید. اگر هم به دنبال روش سادهتری هستید که با کیوت سمت سرور باشه، از Cutelyst هم میتونید استفاده کنید.
-
1 امتیازآیا این واقعاً امکانپذیر است؟ پاسخ : بله! من میدانم که ممکن است این مبحث تحت سی++ بسیار پیچیده و یک کار بیهودهای باشد! اما واقعیت این است که تکنیکهای پنهان بسیاری وجود دارد که ممکن است همه از آن باخبر نباشند! من قبلاً در مورد اینکه تحت ++C وبسایت میشه طراحی کرد یا خیر تحقیقاتی انجام داده بودم، از لحاظ امکان بودنش جواب مثبت بود اما اینکه به راحتی طراحی تحت Php یا دیگر زبانهای برنامهنویسی باشه خیر! خُب طبیعیه چون شما بسیار راحت یه اسکریپت رو مینویسی و روی سرور اجراش میکنی و سایت شما به خوبی و خوشی بالا میاد! ممکن است در همین قسمت از موضوع شما به این نتیجه رسیده باشید که خُب نیازی به ادامهٔ بحث نداریم! وقتی کار سختیه پس منطقی نیست و شما احتمالاً دیوانهای!!! ? واقعیت جریان این است بر خلاف آن چیزی که تصور کردهایم طراحی وبسایت با سیپلاسپلاس نه تنها بسیار راحت است بلکه بسیار هم جذاب خواهد بود! اما در نگاه اول ممکن است یک سری محدودیتهارا داشته باشد که همهٔ این موارد با کمی تأمل و بررسی قابل حل هستند به قدری که وقتی درگیر این جریان باشید شیفتهٔ آن خواهید شد. مزایای یک وبسایت تحت سیپلاسپلاس نسبت به دیگر زبانهای رایج سرعت خارقالعاده و غیر قابل مقایسه با زبانهای رایج امنیت بهتر کدهای شما مدیریت سادهتر و انعطافپذیری بالا مصرف بسیار بهینه و غیر قابل تصور از منابع سرور دسترسی نامحدود به کتابخانهها عدم محدودیت در دسترسی به برنامهنویسی سطح پایین عدم محدودیت در استفاده از توابع سیستمعامل عدم محدودیت در مدیریت سیستم و هر ویژگی دیگری که در زبانهای اسکریپتی اگر به آن نیاز داشته باشید مجبور هستید تا به صورت اکستنشن آن را تحت سیپلاسپلاس باز نویسی کنید. سیستم راهانداز وبسرور چگونه است؟ در هر سروری CGI به شما امکان این را میدهد که بتوانید تحت پروتکلهای استاندارد برنامههای تحت وب را اجرا کنید. شما میتوانید تحت آن و یا موارد دیگری مانند FastCGI و WSGI و دیگر موارد بهینه شدهٔ آن برنامهٔ تحت وب را بر روی سرور خود اجرا کنید. طراحی قالب هماهنگی با HTML, JavaScript, Css در سیپلاسپلاس چگونه خواهد بود؟ همهٔ گزینههای مربوط به وب را شما بدون هیچ محدودیتی در اختیار خواهید داشت. شما هیچ محدودیتی در استفاده از ویژگیهای HTML5 یا CSS3 و یا JavaScript و دیگر فریمورکها و کتابخانههای کارآمدی چون Angular.JS را نخواهید داشت. بنابراین از نظر طراحی رابط یک وبسایت همانند دیگر زبانهای رایج میتوانید روی آن حساب کنید. طراحی هسته و بکاِند وبسایت چگونه خواهد بود؟ همانند زبانها و فریمورکهای رایج تحت وب شما در سیپلاسپلاس میتوانید هستهٔ وبسایت یا سیستم وبسایت خود را تحت استاندارد سیپلاسپلاس و هر کتابخانهای که میپسندید و یا به آن تسلط دارید پیاده سازی کنید! به شرطی که قابلیتهای آن کتابخانه پاسخگوی نیازهای شما باشد. با این حساب شما میتوانید حتی سیستم مدیریت محتوای (CMS) خود را طراحی کنید! ? بله سیستم مدیریت محتوا تحت سیپلاسپلاس! کاملاً جدی هستیم ? قبل از هر چیز یک مزیت بسیار بزرگ در کنار مزیتهای دیگر این است که یک CMS تحت سیپلاسپلاس میتواند داشته باشد مصرف بهینه از منابع سرور خواهد بود. برای مثال در یک مقایسهٔ ساده و آزمایشی نتیجهٔ بسیار جالبی ارائه شده است. همانطور که میدانید Wordpress به عنوان یک سیستم مدیریت محتوای (بلاگ) شناخته شده و تحت Php توسعه یافته است. نسخهٔ سریعتر و بهینهتر آن با نام Ghost تحت Node.JS توسعه یافته است که ما نسخهٔ توسعه یافتهٔ آن را با یک عمل مشابه در C++1z مورد بررسی قرار داده ایم که نتایج آن بسیار جالب است! مصرف حافظه سیستم مدیریت محتوای Tegra ۳۵۰۰ درخواست در هر ثانیه 3.6 مگابایت سیستم مدیریت محتوای Ghost 100 درخواست در ثانیه 120 مگابایت پشتیبانی از پایگاههای داده به لطف کتابخانههای عظیم سیپلاسپلاس امکان مدیریت یک وبسایت تحت پایگاههای داده مختلفی ممکن است. برای مثال تحت Qt شما میتوانید به رایجترین درایورهای بانکاطلاعاتی دسترسی داشته و سیستم خود را به آنها مجهز کنید. نکته: احتمالاً در برنامهنویسی با نود جیاس و پیاچپی شناختی با کتابخانههای OpenSSL, Libcurl و موارد این چنینی داشته اید! کتابخانههای فوق عضو لیست کتابخانههای C و ++C هستند. بنابراین شما علاوه بر دسترسی مستقیم بر آنها به هزاران و شاید میلیونها کتابخانه در دنیا سیپلاسپلاس خواهید داشت. نمونهٔ اولیه اما شوقآور برای اثبات امکان طراحی وبسایت تحت سیپلاسپلاس چندی پیش من تصمیم گرفتم تا سیستم وبسایتی را تحت Php7 برای یکی از استارتآپها طراحی و پیاده سازی کنم که در این پست به آن اشاره شده است. از آنجایی که به لطف کتابخانهٔ Qt برنامههای سمت کاربر را توسط سیپلاسپلاس پیاده سازی کرده بودم به این فکر افتادم چرا سمت سرور و بخش وبسایت هم با آن هماهنگ نشود!؟ اینگونه هماهنگی بین برنامهها و پرفرمنس همهٔ آنها بسیار افزایش خواهد یافت در اولین نگاه این تفکر بسیار ناشیانه و بسیار ناممکن بود! تنها روشی که به کار گرفته بودم ارسال اطلاعات از طرف کاربر به سمت سرور و مدیریت آنها تحت معماری Restful Api بود که در قالب JSon آنها را تجزیه و مدیریت میکردم. با کمی تحقیق در مورد ویژگیهای سمت وب تحت Fast-CGI, uWSGI, DJango, ClearSilver و موارد مرتبط با آنها سعی کردم تا صفحهٔ بسیار سادهای از HTML را توسط سیپلاسپلاس هندل کنم. این کار نتایج بسیار موفقیت آمیزی را در بر داشت تا نتیجهٔ آن تبدیل به یک پروژهٔ سیستم مدیریت محتوا تحت ++C شد. من پروژهای با نام مفهومی Tegra که نام پروژهٔ قبلی تحت Php بود را در محیط Qt Creator با C++17 و کتابخانهٔ Qt باز سازی کرده و هستهٔ اولیهٔ آن را برای اجرای چند صفحه از یک وبسایت، احراز هویت، بازخوانی و نمایش لیستی از خبرها و مدیریت متا تگها و آدرس صفحات مربوط به هر صفحه را ایجاد کردم. سعی کرده ام در کمترین زمان ممکن برای آزمایش یک سری ویژگیهای اولیه از یک وبسایت آنها را مورد بررسی قرار بدم که عبارتند از هماهنگی با فریمورکهای طراحی مانند BootStrap و یا Angular.JS که خوشبختانه همهچیز بسیار خوب در کنار همدیگه کار میکنند. هستهٔ سیستم به صورت جدا و معماری طراحی آن بر پایهٔ MVC مورد آزمایش قرار گرفته است. در زیر تصاویری از صفحات تولید شده تحت سیستم مدیریت محتوای ساخته شده با سیپلاسپلاس را مشاهده میکنید. ? همه چیز در قدمهای اول قرار دارد و با توجه به سادگی تولید وب سایت بر خلاف تصوری که داشتیم بسیار توسعه و جای پیشرفت خواهد داشت. بخشی از نمونه کدهای این سیستم به صورت زیر آورده شده است تا ذهنیتی برای توسعهدهندگان ارائه شود: تکه کُد زیر عمل ارسال اطلاعات و تمامی لینکهای مربوط به بوت استرپ را برای سمت HTML ارائه میکند که در قالب استاندارد جدید C++17 آورده شده است: auto bootstrapCss = bootStrapLib.find("css"); if(bootstrapCss != bootStrapLib.end()) { c->setStash("BootstrapCss", bootstrapCss->second.c_str()); std::cout << "Found " << bootstrapCss->first << " " << bootstrapCss->second << '\n'; } کد مربوط به سمت قالب به صورت زیر خواهد بود: <!-- Bootstrap core css --> <link href="{{BootstrapCss}}" rel="stylesheet"> نتیجهٔ فوق در صورتی که CDN بر روی لوکال تنظیم شده باشد از روی کدهای کامپایل شده و یا استاتیک فراخوانی خواهد شد. در غیر اینصورت از روی یکی از سرورهای CDN فراخوانی میشوند. نحوهٔ ارسال متغیر از سمت سیپلاسپلاس به قالب بسیار ساده است! بسیار ساده از Php و یا Node.JS میباشد. با در نظر گرفتن ارسال اطلاعات از سمت سیپلاسپلاس به سمت رابط کاربری کافی است نام متغیرها را در قالب خود اعمال کنید. {% for post in news %} <div class="blog-post"> <h2 class="blog-post-title"><a href="news/{{post.uri}}">{{post.title}}</a></h2> <p class="blog-post-meta">{{post.date}} by <a href="#">{{post.author}}</a></p> <p>{{post.announcement|safe}}</p> </div><!-- /.blog-post --> {% endfor %}</div> این ساختار بر پایهٔ ساختار Angular.JS و DJango پیاده سازی شده است که به طور کامل پشتیبانی میشود. فعال سازی فناوری Angular.JS بر روی این سیستم جهت طراحی قالب تنها با دو دستور ساده اعمال میشود: <!-- Link to AngularJS --> <script src= "{{AngularJs}}"></script> <!-- Enable AngularJS Engine --> {{AngularJsSync|safe}} این دستورات در هستهٔ سیستم مدیریت محتوا در کلاسی با نام Template پردازش و در نهایت به سمت HTML هندل میشوند. بخشی از دستورات سمت هسته در سیپلاسپلاس ۱۷ برای مثال ارسال عنوان صفحه به صورت زیر است: std::optional<std::string> LoadListTemplate::getTitle() const { if (isset(title)) { return title; } else { return std::nullopt; } } سمت HTML کافی است دستور فوق را در نظر بگیریم: <title>{{title}}</title> اینها مثالهایی از مراحل توسعهٔ این سیستم است که میدانم آنچنان گسترده نیست، اما برای ثابت کردن طراحی و توسعهٔ وبسایت تحت سیپلاسپلاس مثالهای روشنی هستند. موفق و سربلند باشید! اطلاعیههای مربوط به این پروژه احتمالاً در کانالها و گروه تلگرامی و همین مرجع بازگو و در اختیار شما قرار گیرد.
-
1 امتیازسلام، کیوت با توجه به استانداردهای پیشنهادی گوگل پیش میره؛ بنابراین حداقل نسخه بر اساس آخرین تغییرات تا به این تاریخ نسخهٔ ۷.۰ اندروید است.
-
1 امتیازدرود، برای این کار از وبسرویس استفاده کنید، از رابطها و معماریهایی مثل Restful Api.
-
1 امتیازفایل صوتیِ ترس و استرس در مسیر یادگیری بازار کار زمان اختصاص یافته شده : ۱۱ دقیقه و ۱۷ ثانیه. Fear&Stress-Podcast.mp3
-
1 امتیازفایل صوتیِ عدم توانایی تصمیم گیری در مسیرِ یادگیری و رسیدن به موفقیت. زمان اختصاص یافته شده : ۷ دقیقه و ۳۱ ثانیه. Podcast-04.mp3
-
1 امتیاز
-
1 امتیاز
-
1 امتیاز
-
1 امتیازدرود، برای این کار شما باید به شیوهٔ Button تغییرات رو اعمال کنید، چرا که نوع کنترل TabButton مشتق شدهٔ کنترل اصلی است. برای این کار کافیه به روش سفارشی سازی Button عمل کنید. مثال: import QtQuick 2.12 import QtQuick.Controls 2.12 TabButton { id: control text: qsTr("Button") contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 100 implicitHeight: 40 opacity: enabled ? 1 : 0.3 border.color: control.down ? "#17a81a" : "#21be2b" border.width: 1 radius: 2 } }
-
1 امتیازپادکستِ مربوط به شفافسازی تقریبی از مسیرِ توسعهدهندگی تحت سی++ و ساخت محصولِ هدفمند زمان مورد نیاز : ۲۰ دقیقه و ۱۱ ثانیه Podcast-03.mp3
-
1 امتیازپادکستِ مربوط به اهمیت شکست و تجربه زمان مورد نیاز : ۳ دقیقه و ۸ ثانیه. Podcast-02.mp3
-
1 امتیازپادکستِ مربوط به نحوهٔ قیمتگذاری بر روی پروژه زمان مورد نیاز : ۱۰ دقیقه و ۴۹ ثانیه. Pricing-Podcast.mp3
-
1 امتیازجزئیات در ۱۱ ++C و برخی بهبودها در ویرایش ۱۷ جدا کننده رقم استاندارد ۱۱ تا قبل از استاندارد ۱۴ شما مجبور بودید تعداد رقمها و یا صفرها را بشمارید. از استاندارد ۱۴ به بعد دیگر نیازی به این کار نیست. این کار در زمان محاسبهٔ آدرس در کلمه، مرزهای رقمی یا نیم کاراکترها مفید خواهد بود. در واقع با گروهبندی ارقام کد شما رساتر خواهد شد. int no = 1'000'000; long addr = 0xA000'EFFF; uint32_t binary = 0b0001'0010'0111'1111; تعریف نام مستعار (Type aliases) استاندارد ۱۱ از لحاظ معنایی مشابه typedef است، هرچند نامهای مستعار تعریف شده به این شیوه سادهتر بوده و تحت انواع الگوها سازگارتر هستند. به مثالهای زیر توجه کنید: template <typename T> using dynamicArray = std::vector<T>; dynamicArray<int> nums; // equivalent to std::vector<int> using func_ptr = int (*)(int); و یا اگر بخواهید نام مستعاری از یک نوع std::map با کلید و مقدار از نوع رشته تعریف کنید، آنگاه به صورت زیر خواهد بود: using mapString = std::map<std::string, std::string>; این روش برای موارد متنوعی مورد استفاده قرار که قبل و بعد از وجود آن را در مثال زیر میبینیم: // C++11 using counter = long; // C++03 equivalent: // typedef long counter; // C++11 using fmtfl = std::ios_base::fmtflags; // C++03 equivalent: // typedef std::ios_base::fmtflags fmtfl; fmtfl fl_orig = std::cout.flags(); fmtfl fl_hex = (fl_orig & ~std::cout.basefield) | std::cout.showbase | std::cout.hex; // ... std::cout.flags(fl_hex); // C++11 using func = void(*)(int); // C++03 equivalent: // typedef void (*func)(int); // func can be assigned to a function pointer value void actual_function(int arg) { /* some code */ } func fptr = &actual_function; template<typename T> using ptr = T*; // the name 'ptr<T>' is now an alias for pointer to T ptr<int> ptr_int; الفاظ رشتهای تعریف شده توسط کاربر (User-defined literals) استاندارد ۱۱ در مواقع نیاز شما مجبورید با اصطلاحات واضحی مثل MB, KB, GB یا km، cm و یا واحدهای دیگری جهت تبدیلات در زمان اجرا کاری انجام دهید. اکنون به عنوان کاربر میتوانید اصلاح مورد نیاز خود را همانند انواع pt (انواع ابتدائی) دیگر انجام دهید. این شیوه برای واحدها و اندازهگیری بسیار مناسب است. اضافه کردن constexpr اثر هزینهٔ صفر از کارایی را در زمان اجرا فراهم میکند. using ull = unsigned long long; constexpr ull operator"" _KB(ull no) { return no * 1024; } constexpr ull operator"" _MB(ull no) { return no * (1024_KB); } int main() { std::cout << 1_KB << std::endl; std::cout << 1_MB << std::endl; return 0; } ویژگی مقداردهی لیست اولیه (std::initializer_list) استاندارد ۱۱ std::pair<int, int> p = {1, 2}; std::tuple<int, int> t = {1, 2}; std::vector<int> v = {1, 2, 3, 4, 5}; std::set<int> s = {1, 2, 3, 4, 5}; std::list<int> l = {1, 2, 3, 4, 5}; std::deque<int> d = {1, 2, 3, 4, 5}; std::array<int, 5> a = {1, 2, 3, 4, 5}; این شیوه مشابه آرایهها به سبک C مقادیر را مستقیماً با لیست مقدار دهندهٔ اولیه «std::initializer_list» اختصاص میدهد. همچنین به لطف استاندارد ۱۱ این مورد در مورد نگهدارندههای تو در تو هم صدق میکند. ویژگی auto و decltype استاندارد ۱۱، بهبود و اضافات در استاندارد ۲۰ متغیرهای تعریف شده به وسیلهٔ کلمهٔ کلیدی auto بر اساس نوع مقدار توسط کامپایلر استنباط میشوند. متغیرهای تعرف شده به کمک کلمهٔ کلیدی decltype بر اساس بررسی موجودیت یا نوع و مقادیر عبارت تعیین میشوند. این ویژگیها به شدت برای خواندن، به ویژه انواع پیچیده مفید است. auto a = 3.14; // double اجازه دهید یک مثال با ترکیب auto و decltype داشته باشیم. به عنوان مثال، توابع میتوانند به وسیلهٔ کلمهٔ کلیدی auto نیز نوع بازگشتی خود را استنباط کنند. در استاندارد ۱۱ نوع بازگشتی باید به طور صریح یا با استفاده از نوع decltype رمزگشایی شود، به مثالهای عادی و الگو (template) مانند زیر توجه کنید: auto getResult(std::string var) -> decltype (var) { return var; } template <typename X, typename Y> auto add(X x, Y y) -> decltype(x + y) { return x + y; } add(1, 2); // == 3 add(1, 2.0); // == 3.0 add(1.5, 1.5); // == 3.0 ویژگی Range-based for-loops استاندارد ۱۱ به علاوهٔ اضافات و بهبودها در استاندارد ۱۷ و ۲۰ یک نحوِ شیرین برای تکرار عناصر در یک نگهدارنده یا ظرف (container) std::vector<int> v = {0, 1, 2, 3, 4, 5}; for (const int& i : v) // access by const reference std::cout << i << ' '; std::cout << '\n'; برای بررسی برخی از ویژگیهای مرتبط با این موضوع به مقالات زیر مراجعه کنید: اشارهگرهای هوشمند استاندارد ۱۱، بهبودها در استاندارد ۱۷ استاندارد ۱۱ با خود اشارهگرهای هوشمند را معرفی کرده است مانند std::unique_ptr، std::shared_ptr و std::weak_ptr که سپس std::auto_ptr در استاندارد ۱۷ به عنوان منسوخ شده معرفی و حذف شده است. std::unique_ptr<int> p = std::make_unique<int>(128); برای آشنایی با این ویژگی، لازم است در رابطه با اصطلاح RAII آشنا شوید، برای این منظور مقالهٔ زیر را برای مطالعه پیشنهاد میکنم. صفتهای استاندارد جدید مانند، [[fallthrough]]، [[maybe_unused]] و [[nodiscard]] استاندارد ۱۷ این بحث به خودی خود بسیار جذاب است، بنابراین برای آن یک مقالهٔ ویژه در نظر گرفتهام که در ادامه میتوانید به آن مراجعه کنید. ویژگی فضاهای نام تو در تو (Nested namespace) استاندارد ۱۷ فضاهای نام یکی از کاربردیترین ویژگیهای سی++ از زمان استاندارد ۱۱ به بعد میباشد که نحوهٔ تعریف آن به صورت زیر است: namespace Base { namespace Person { class PersonInfo { public: std::string name = {"Kambiz"}; }; } } در ادامهٔ استاندارد ۱۷ بهبود آن به شیوهٔ تو در تو صورت گرفته است و میتواند به صورت زیر تعریف شود: namespace Base::Person { class PersonInfo { public: std::string name = {"Kambiz"}; }; } در نهایت دسترسی به فضای نام و اعضای آن به همان شیوهٔ ساده ممکن است: Base::Person::PersonInfo pInfo; std::cout << pInfo.name << std::endl; یک کاراکتر u8 لفظی استاندارد ۱۷ این ویژگی برای ترجمهٔ صحیح کاراکترها به اسکی (ASCII) در پلتفرمهای مختلف استفاده میشود. auto c = {u8'C'}; و یا به صورت یک رشتهٔ کامل: auto str = u8"سلام"; std::cout << str << "/n"; امکان استفاده از auto در template استاندارد ۱۷ این ویژگی امکان این را میدهد تا نوع پارامترها را در الگوها تعریف کنیم، در استاندارد ۱۴ این ویژگی به صورت زیر ممکن است: template<typename Type, Type x> constexpr auto value = x; int main() { auto x = value<int,3>; return 0; } و اینک به لطف استاندارد ۱۷ استفاده از کلمهٔ کلیدی auto نیز فراهم شده است که به طور زیر تعریف میشود: template<auto x> constexpr auto value = x; int main() { auto x = value<3>; return 0; } نوع متغیر x توسط کامپایلر استنباط میشود، البته باید در نظر داشت این ویژگی در استفاده از variadic templates هم کاربرد دارد. به مثال زیر توجه کنید: template<auto ... values> struct A {}; int main() { auto k = A<1, 2, 'c'>(); return 0; } الفاظ رشتهای (لیترال) با ممیز شناور (Floating point) در مبنای هگزادسیمال استاندارد ۱۷ در استاندارد ۱۷ ممیز شناور در مبنای هگزادسیمال اضافه شده است. اگر یک حرف شناور لفظی، آغازش با دنبالهٔ کاراکترهای 0x یا 0X باشد، آن در مبنای هگزا دسیمال شناور محسوب میشود. در غیر این صورت در مبنای شناور دسیمال (مبنای ۱۰) تعریف میشود. 0x | 0X hex-digit-sequence exponent suffix double d = 0x1.2p3; // hex fraction 1.2 (decimal 1.125) scaled by 2^3, that is 9.0 به مثال زیر توجه کنید: #include <iostream> int main() { std::cout << 58. << '\n' << 4e2 << '\n' << 123.456e-67 << '\n' << .1E4f << '\n' << 0x10.1p0 << '\n'; } نتیجهٔ تحت این ویژگی به این صورت است: 58 400 1.23456e-65 1000 16.0625
-
1 امتیازمدتی قبل بود که من در رابطه با شاخصهای در حال رشد زبانهای برنامهنویسی در کانالهای شخصی نظری داده بودم که با توجه به وضعیت شاخص، زبان برنامهنویسی ++C سریعترین رشد را بعد از مدتها به خود اختصاص داده است. این تغییرات و بیداری زبان طبق انتظاری که داشتم بعد از ظاهر شدن زبان برنامهنویسی Rust در بین ۲۰ زبان برنامهنویسی برتر و همچنین نهایی شدن استانداردهای 2a و پیشرفتهای اخیر به خصوص رضایتبخشی کاربران از استاندارد 17 زبان ++C رخ داده است که دور از انتظار هم نبود. طبق شاخص محبوبیت طی چند سال گذشته، ++C با توجه به شاخص TIOBE در سپتامبر، سریعترین زبان در حال رشد در بسته برنامهنویسی است. این زبان در سالهای گذشته، محبوبیت سهم خود را در فراز و نشیبها داشته است. اما با مقیاسه با سالهای گذشته در حال حاضر رسماً سریعترین رشد را در بین تمامی زبانهای تحت پوشش اتوماسیون QA در شرکت Tobie را دارد. با این حال مدیرعامل Tobie جناب Paul Jansen گفته است، من فکر میکنم که استاندارد جدید سی++ یکی از دلایل این رشد اصلی باشد. به خصوص ویژگیهای جدید module که قرار است جایگزین مکانیزم وحشتاک قبلی شود. با این روند سی++ بیشترین رشدها که متعلق به #C با ۱.۱۸+ و R با ۱.۳۳+ را شکست میدهد.
-
1 امتیازدر این مقاله من قصد دارم به معرفی ده فریمورک برتر جهان در بازهٔ سالهای ۲۰۱۹ و ۲۰۲۰ اشاره کنم که در حوزهٔ صنعت وب کاربرد دارند. معمولاً در سایتها، وبلاگها و گروههای تلگرامی حرف از فریمورکهای شناخته شدهای مانند Asp.net core و یا Laravel به گوش میرسد. اما واقعیت این است که فریمورکهایی که در مورد آنها بحث میشود جایگاه خاصی در بین فریمورکهای قدرتمند و به عنوانی ناشناخته مانند Drogon، h2o، ulib و غیره ندارند! جالب است بدانید فریمورکهایی که در ادامه نامهایشان را میشنوید به قدری سریع و قدرتمند هستند که مو بر تنِ شما سیخ خواهد کرد! برای مثال در این مقایسه جایگاه فریمورکهای داتنت به بالاتر از ۵۰ و لاراول به بیشتر از ۲۰۰ رتبه میرسد! این در حالی است که بر خلاف انتظارِ عام، فریمورکهای تحت سی/سی++ و راست به عنوان سریعترین فریمورکها شناخته میشوند. در واقع مقایسه بر اساس نتایج گرفته شده از مرجع Techempower میباشد که هر ساله یک مقایسه در رابطه با کارآیی و کیفیت فریمورکهای وب میپردازد. سنجشِ فوق بر اساس وظایفی مانند سریالسازی جیسان، دسترسی به پایگاه داده و عملیات سمت سرور، پردازش و غیره میباشد. در این آزمایشها عملکرد فریمورک بر روی سیستمعامل، به صورت فولاِستک و میکرو اندازهگیری شده است که هر کدام را در رتبهٔ خاصی از وضعیت آن سوق میدهد. بهترین فریمورکها از نظر بنچمارک (کارآیی) در سال ۲۰۱۹ در دورِ ۱۸ بین ۲۲۰ فریمورک متعلق به h2o و ulib بوده است. کتابخانهٔ h2o یکی از قویترین مواردی است که میتوان به آن اشاره کرد. در سال ۲۰۲۰ این رتبهبندی به نفعِ فریمورک جدیدتری به نام دراگون (Drogon) و مجدداً ulib جمع بندی شده است که نشان میدهد فریمورک ulib به عنوان یکی از برترین فریمورکهای نوشته شده تحت سی و سی++ و همچنین دراگون تحت استانداردهای ۱۴ و ۱۷ زبان برنامهنویسی سیپلاسپلاس معرفی شده است. بنابرین بهتر است در مورد دراگون بیشتر بدانیم: این فریمورک تحت زبان برنامهنویسی ++C در استاندارد ۱۴ و ۱۷ توسعه یافته و بر روی سکوهای لینوکس، مک و ویندوز قابل اجراست. دراگون تحت ویژگی non-blocking I/O کار میکند و سرعت را همراه با دقت بسیار بالایی به خصوص بر روی پلتفرمهای FreeBSD تضمین میکند. لینک مخزن توسعه و کدهای دراگون. مثال از کد اولیه: #include <drogon/drogon.h> using namespace drogon; int main() { app().setLogPath("./") .setLogLevel(trantor::Logger::kWarn) .addListener("0.0.0.0", 80) .setThreadNum(16) .enableRunAsDaemon() .run(); } با توجه به مقایسههای صورت گرفته در آزمایشهای مختلف زیر رتبهبندی فریمورکها مشخص میشود. آزمایشهای فوق بر روی پردازندهٔ Dell R440 Xeon Gold صورت گرفته است که در این لینک آمده است. JSON serialization Single query Multiple queries Fortunes Data updates Plaintext آزمایشهای مربوطه تنها به ۱۰ مورد اول اشاره کرده است، بنابراین برای مشاهدهٔ لیست بیشتر و جزئیات آنها به مرجع آن مراجعه کنید.
-
1 امتیازهنگامیکه شما برای اولین بار از C به CPP مهاجرت می کنید، یا اصلا برنامه نویسی را قصد دارید با CPP شروع کنید، با مفاهیم متعددی روبرو خواهید شد که شاید برای شما جالب باشند که بدانید، این ایده ها چطور شکل گرفتند، چطور به CPP افزوده شدند و اهمیت آن ها در عمل (هنگام برنامه نویسی و توسعه نرم افزار) چیست. در این پست وبلاگی IOStream، به این خواهیم پرداخت که ایده Overloading و Template و Auto Deduction چطور از CPP سر در آوردند. همانطور که شما ممکن است تجربه کرده باشید، هنگامیکه برنامه نویسی و توسعه نرم افزاری را با C شروع می کنید، برنامه شما چیزی بیش از یک مجموعه بی انتها از توابع و استراکچرها و متغیرها و اشاره گرها و ... نخواهند بود. از همین روی شما مجبور هستید مبتنی بر ایده مهندسی نرم افزار و پارادیم برنامه نویسی ساخت یافته، برای هر کاری یک تابع منحصربفرد پیاده سازی کنید. این تابع باید از هر لحاظی از قبیل نام، نوع ورودی ها، نوع خروجی و حتی نوع عملکرد منحصربفرد باشد تا بتواند یک کار را به شکل صحیح کنترل کند که همین مسئله می تواند در پیاده سازی برخی نرم افزارها، انسان را در جهنم داغ و سوزان قرار بدهد. مثلا پیاده سازی یک برنامه محاسباتی مانند ماشین حساب که ممکن است با انواع داده های محاسباتی مانند عدد صحیح (Integer) و عدد اعشاری (Float) رو به رو شود. از همین روی فرض کنید، ما قرار است یک عمل محاسباتی مانند جمع از برنامه ماشین حساب را پیاده سازی کنیم. برای اینکه برنامه به شکل صحیحی کار کند، باید عمل جمع یا همان Add برای انواع داده های موجود از قبیل عدد صحیح و اعشاری پیاده سازی شود. اگر شما این کار را انجام ندهید، برنامه شما به شکل صحیحی کار نخواهد کرد (یعنی نتایج اشتباه ممکن است برای ما تولید کند). در تصویر زیر، نمونه این برنامه و توابع مرتبط با آن پیاده سازی شده است: #include <stdio.h> int AddInt(int arg_a, int arg_b) { return arg_a + arg_b; } float AddFloat(float arg_a, float arg_b) { return arg_a + arg_b; } double AddDouble(double arg_a, double arg_b) { return arg_a + arg_b; } int main(int argc, const char* argv[]) { int result_int = AddInt(1, 2); float result_float = AddFloat(10.02f, 21.23f); double result_double = AddDouble(9.0, 24.3); printf("Result Integer: %d", result_int); printf("Result Float: %f", result_float); printf("Result Double: %lf", result_double); return 0; } به برنامه بالا دقت کنید. ما سه تا تابع Add با نام های منحصربفرد داریم که سه نوع داده مجزا را به عنوان ورودی دریافت می کنند، سه نوع نتیجه مجزا بازگشت می دهند، اگرچه پیاده سازی آن ها کاملا مشابه هم دیگر است و تفاوتی در پیاده سازی این سه تابع وجود ندارد. ولی به هر صورت، اگر به خروجی دیزاسمبلی برنامه مشاهده کنید، دلیل این مسئله را متوجه خواهید شد که چرا هنگام برنامه نویسی با زبان C، به نام های منحصربفرد نیاز است، چون اگر توابع نام های مشابه با هم داشته باشند، لینکر نمی تواند به دلیل تداخل نام (Name Conflict)، آدرس آن ها را محاسبه یا اصطلاحا Resolve کند. همانطور که در تصویر بالا خروجی دیزاسمبلی برنامه Add را مشاهده می کنید، اگر توابع نام مشابه داشتند، در هنگام فراخوانی (Call) تابع Add تداخل رخ می داد، چون دینامیک لودر سیستم عامل دقیقا نمی داند که کدام تابع را باید فراخوانی کند. برای همین نیاز است وقتی برنامه نوشته می شود، نام توابع در سطح کدهای اسمبلی و ماشین منحصر بفرد باشد. به هر صورت، به نظر شما آیا راهی وجود دارد که ما پیاده سازی این نوع توابع را ساده تر کنیم یا حداقل بار نامگذاری آن ها را از روی دوش توسعه دهنده و برنامه نویس برداریم؟ بله امکان این کار وجود دارد. مهندسان CPP با افزودن ویژگی Overloading و Name Mangling یا همان بحث Decoration مشکل برنامه نویسان در پیاده سازی توابع با نام های منحصربفرد را حل کردند (البته کاربردهای دیگر هم دارد که فعلا برای بحث ما اهمیت ندارند). ویژگی اورلودینگ در CPP به ما اجازه خواهد داد یک تابع با عنوان Add پیاده سازی کنیم که تفاوت آن ها فقط در نوع ورودی و نوع خروجی است. به عنوان مثال، در قسمت زیر، کد برنامه Add را مشاهده می کنید که با قواعد CPP بازنویسی شده است. #include <iostream> int Add(int arg_a, int arg_b) { return arg_a + arg_b; } float Add(float arg_a, float arg_b) { return arg_a + arg_b; } double Add(double arg_a, double arg_b) { return arg_a + arg_b; } int main(int argc, const char* argv[]) { int result_int = Add(1, 2); float result_float = Add(10.02f, 21.23f); double result_double = Add(9.0, 24.3); std::cout << "Result Integer: " << result_int << std::endl; std::cout << "Result Float: " << result_float << std::endl; std::cout << "Result Double: " << result_double << std::endl; return 0; } همانطور که مشاهده می کنید، ما اکنون سه تابع با نام Add داریم. ولی شاید سوال پرسیده شود که چطور لینکر متوجه تفاوت این توابع با یکدیگر می شود درحالیکه هر سه دارای یک نام واحد هستند. اینجاست که مسئله Name Mangling یا همان Decoration نام آبجکت ها در CPP مطرح می شود. اگر شما برنامه مذکور را دیزاسمبل کنید، متوجه تفاوت کد منبع (Source-code) و کد ماشین/اسمبلی (Machine/Assembly-code) خواهید شد. همانطور که در خروجی دیزاسمبلی برنامه اکنون مشاهده می کنید، توابع اگرچه در سطح کد منبع دارای نام مشابه با یکدیگر بودند، اما بعد کامپایل نام آن ها به شکل بالا تبدیل می شود. به این شیوه نام گذاری Name Mangling یا Decoration گویند که قواعد خاصی در هر کامپایلر برای آن وجود دارد. این ویژگی موجب می شود در ادامه لینکر بتواند تمیز بین انواع توابع Add شود. به عنوان مثال، تابع نامگذاری شده با عنوان j__?Add@YAHH@Z تابعی است که به نوعی از تابع Add اشاره دارد که ورودی هایی از نوع عدد صحیح دریافت می کند. این شیوه نامگذاری خلاصه موجب خواهد شد لینکر بتواند به سادگی بین توابع تمایز قائل شود. با این حال هنوز یک مشکل باقی است، و آن هم تکرار مجدد یک پیاده سازی برای هر تابع است. به نظر شما آیا راهی وجود دارد که ما از پیاده سازی مجدد توابعی که ساختار مشابه برای انواع ورودی ها دارند، جلوگیری کنیم؟ باید بگوییم، بله. این امکان برای شما به عنوان توسعه دهنده CPP در نظر گرفته شده است. ویژگی که اکنون به عنوان Templateها در مباحث Metaprogramming یا Generic Programming استفاده می شود، ایجاد شده است تا این مشکل را اساساً برای ما رفع کند. با استفاده از این ویژگی کافی است، طرح یا الگوی یک تابع را پیاده سازی کنید، تا در ادامه خود کامپایلر مبتنی بر ورودی هایی که به الگو عبور می دهید، در Backend، یک نمونه تابع Overload شده مبتنی بر آن الگو برای نوع داده شما ایجاد کند. #include <iostream> template <typename Type> Type Add(Type arg_a, Type arg_b) { return arg_a + arg_b; } int main(int argc, const char* argv[]) { int result_int = Add(1, 2); float result_float = Add(10.02f, 21.23f); double result_double = Add(9.0, 24.3); std::cout << "Result Integer: " << result_int << std::endl; std::cout << "Result Float: " << result_float << std::endl; std::cout << "Result Double: " << result_double << std::endl; return 0; } به عنوان مثال، در بالا تابع Add را مشاهده می کنید که نوع داده ورودی این تابع و حتی نوع خروجی آن مشخص نشده است و در قالب Typename به کامپایلر معرفی شده است. این یک الگو برای تابع Add است. کامپایلر اکنون می تواند مبتنی بر ورودی هایی که به تابع هنگام فراخوانی یا اصطلاحا Initialization عبور می دهیم، یک نمونه تابع Overload شده از آن الگو ایجاد کند و در ادامه آن را برای استفاده در محیط Runtime فراخوانی کند. حال اگر برنامه بالا را دیزاسمبل کنید، مشاهده خواهید کرد که کامپایلر از همان قاعده Overloading استفاده کرده است تا نمونه ای از تابع Add متناسب با نوع ورودی هایش ایجاد کند. هنوز می توان برنامه نویسی با CPP را جذاب تر و البته ساده تر کرد، اما چطور؟ همانطور که در قطعه کد بالا مشاهده می کنید، هنوز ما باید خود تشخیص دهیم که نوع خروجی تابع قرار است به چه شکل باشد. این مورد خیلی مواقع مشکل ساز خواهد بود. برای حل این مسئله، در CPP مبحثی در نظر گرفته شده است که آن را به عنوان Auto Deduction می شناسیم که سطح هوشمندی کامپایلر CPP را بالاتر می برد. در این ویژگی خود کامپایلر است که مشخص می کند نوع یک متغیر مبتنی بر خروجی که به آن تخصیص داده می شود، چیست. به عنوان مثال، شما می توانید برنامه بالا را به شکل زیر بازنویسی کنید: #include <iostream> template <typename Type> auto Add(Type arg_a, Type arg_b) { return arg_a + arg_b; } int main(int argc, const char* argv[]) { auto result_int = Add(1, 2); auto result_float = Add(10.02f, 21.23f); auto result_double = Add(9.0, 24.3); std::cout << "Result Integer: " << result_int << std::endl; std::cout << "Result Float: " << result_float << std::endl; std::cout << "Result Double: " << result_double << std::endl; return 0; } با استفاده از ویژگی Auto Deduction و کلیدواژه Auto در برنامه، خود کامپایلر در ادامه مشخص خواهد کرد که تابع Add چه نوع خروجی دارد و همچنین نوع متغیرها برای ذخیره سازی خروجی Add چه باید باشد. به عبارتی اکنون تابع Add هم Value و هم Data type را مشخص می کند که این موجب می شود برنامه نویسی با CPP خیلی ساده تر از گذشته شود. حال اگر به نمونه برنامه آخر نگاه کنید و آن را با نمونه C مقایسه کنید، متوجه خواهید شد که CPP چقدر کار را برای ما ساده تر کرده است. در این پست به هر صورت، قصد داشتم به شما نشان دهم که نحوه تحول CPP به صورت گام به گام چطور بوده است و البته اینکه پشت هر ویژگی در CPP چه منطق کلی وجود دارد. امیدوارم این مقاله برای شما مفید بوده باشد. نمونه انگلیسی این مقاله را می توانید در این آدرس (لینک) مطالعه کنید. میلاد کهساری الهادی
-
1 امتیازمن یک زمانی خدای روی زمینم ++C بود حدودا یک سال و نیم فقط ++C کار بودم تمام تلاشم این بود که همه چیز رو با سیپلاسپلاس بنویسم اما بعد فهمیدم ابزار امده تا کار رو برای مکانیک آسان تر کنه ن این که کار رو سخت کنه مثل این میمونه که شما از آچار فرانسه برای باز کردن پیچ استفاده کنی، زبان هم دقیقا همین طوره. ممنون خیلی مفید بود.
-
1 امتیازسلام و درود خدمت دوستان عزیز، همانطور که میدانید مهمترین و شاید بزرگترین سوال در حوزهٔ برنامهنویسی این است که من باید کدام زبان برنامهنویسی را انتخاب کنم؟! واقعیت امر این است که این سوال همیشه از سمت علاقهمندان مطرح شده است اما هیچگاه یک پاسخ اساسی در مورد آن ارائه نشده است. البته اساتید و برنامهنویسان حرفهای به خوبی میدانند که زبانهای برنامهنویسی به عنوان ابزارهای کمک کار ما کاربرد دارند و به هیچ عنوان نمیتوان یک زبان را به عنوان اولین و آخرین انتخاب در نظر گرفت، اما شناخت در مورد آنها کمک بسیاری در انتخاب ابزارهای مناسب خواهد کرد. در این پُست من قصد دارم در رابطه با انتخاب یک زبان برنامهنویسی بر اساس نیاز و علایق صحبت کنم تا شما عزیزان بتوانید به یک نتیجهٔ مطلوب برسید. بنابراین، قبل از هر چیز این بسیار مهم است که بدانیم یک زبان برنامهنویسی چیست! و چرا باید از آن استفاده کنیم؟! اجازه دهید نگاهی به دلیل استفاده از زبان برنامهنویسی داشته باشیم، چرا از زبان برنامهنویسی استفاده میکنیم؟ به برقراری ارتباط با یکدیگر فکر کنید، انسان برای برقراری ارتباط با همنوعان نیاز به ابزاری به نام زبان دارد که عناصر اساسی آن حروف است. برای مثال حروف خ-ا-ن-ه با ترکیب شدن به خانه تبدیل شده و شما میتوانید آن را درک کنید و این کدی است که شما توسط آن با جهان بیرون خود ارتباط برقرار میکنید. ممکن است کدهای شما توسط یک زبان دیگر مانند زبان انگلیسی ساخته شود، برای مثال h-o-m-e حرفی است که که نتیجهٔ آن Home خواهد بود. در کشور ما معمولاً زبان مادری هریک از ما فارسی، ترکی (آذربایجانی)، عربی، کردی، لُری و دیگر موارد هستند که به صورت بومی آن را فرا میگیریم و با تسلط بسیاری از آن استفاده کرده و منظور همنوعان خود را درک میکنیم. در بحث کامپیوتر، استفاده از زبان انسانی تا حدی کاربرد دارد که فقط خود انسان آن را درک خواهد کرد نه ماشین! چرا که زبان بومی و اصلی کامپیوتر (ماشین) ۰ و ۱ است نه کاراکتر و حرف! ماشینها برای برقراری ارتباط و درک منظور انسان از واحد ۰ و ۱ استفاده میکنند که مجموعهای از آنها به عنوان دستورالعملهای مشخصی برای کامپیوتر قابل درک است. مغز کامپیوتر یعنی واحد پردازشگر مرکزی (CPU) به عنوان پردازندهٔ مرکزی تمامی دادههای شما را در قالب ۰ و ۱ شناسایی میکند و آنها را درک خواهد کرد. بنابراین زبان بومی ماشین بر خلاف انتظار برای انسان بسیار دشوار است و اگر به فکر این باشید که بخواهید از طریق آن با کامپیوتر ارتباط برقرار کنید شما یک دیوانهٔ تمام عیار بشمار خواهید آمد! اجازه دهید منظورم را سادهتر کنم، کامپیوتر منظور شما را از home درک نخواهد کرد! اما اگر به آن بگویید 01101000 01101111 01101101 01100101 مسلماً خواهد فهمید که منظور شما از آن یعنی home است! حالا اگر منظور شما سلام دنیا باشد باید به کامپیوتر بگویید 01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100 و همینطور برای برقراری ارتباط بیشتر باید هزاران، میلیونها و میلیاردها ۰ و ۱ را با اصول زبان ماشین در کنار هم قرار دهید تا شاید بتوانید یک دستورالعمل ساده برای انجام یک کار را به آن انتقال دهید! احمقانست نه؟! وقت و زمان برای ما انسانها بسیار با ارزش است و مسلماً به هدر دادن آن به این روش هرچند دانش بسیار بالایی از مهندسی کامپیوتر میطلبد اما حتی اگر شما یک دانشمند هم باشید بکار گیری این روش دیوانگی محض است! ما که کامپیوتر نیستیم! ما انسانیم! ساختار کامپیوتر بسیار شبیه به ساختار انسان است، همانطور که خالق انسان، خداوند یکتا او را آفرید به آن نیز هوش و قدرتِ تفکر داد تا بتواند بر اساس آن رشد کرده و در مسیر پیشرفت قدم بردارد، انسان نیز از دانستههای خود برای ساختههایش استفاده میکند. کامپیوترها به عنوان ابزارهای ساخت دست بشر دارای ساختار بسیار ساده ولی در عین حال بسیار پیچیده هستند که انسان برای برنامهریزی آن نیاز به ابزارهایی دارد (ابزارهایی برای ایجاد دستورات قابل درک برای ماشین). ابزارهای برنامهریزی برای کامپیوتر همانطور که اشاره شد، کامپیوترها هیچ درکی از کدهایی که انسان مینویسد ندارند! بنابراین ما نیاز به ابزاری داریم تا منظور خود را برای درک کامپیوتر ارائه دهیم. حال آن ابزار میتواند یک مفسر (Interpreter) باشد یا یک کامپایلر (Compiler) ! هر دوی این ابزارها وظیفهٔ دریافت زبان سطح بالا (نزدیک به زبان انسان) و تبدیل (ترجمهٔ آن) به زبان ماشین است. با تفاوت اینکه مفسرها کدهای نوشته شده را خط به خط تفسیر کرده و آنها را برای پردازنده اجرا میکند، در حالی که کامپایلر تمامی کدها را به شیء و هر شیء را به کد باینری یکجا ترجمه کرده و هرجا که نیاز بود آنها توسط پردازنده اجرا میشوند. به بیان سادهتر فرض کنید قرار است به زبان روسی صحبت کنید، شما دو روش خواهید داشت: صحبت کردن به زبان روسی به صورت مستقیم استخدام یک مترجم، صحبت با مترجم و ترج گفتههای شما توسط مترجم به طرف مقابل برخی از مزایا و معایب کامپایلر و مفسر نسبت به یکدیگر نکته ۱: مفسرها کدهای نوشته شده را به صورت خط به خط تفسیر و ترجمه میکند اما کامپایلرها آنها را یکجا ترجمه میکند که دارای یک خروجی مانند یک فایل اجرایی است. نکته ۲: برنامهٔ تولید شده تحت کامپایلر توسط سخت افزار (ماشین واقعی) اجرا میشود در صورتی که برنامهٔ تولید شده با مفسر توسط نرمافزار (ماشین مجازی) اجرا میشود. نکته ۳: کامپایلرها عملیات بهینهسازی یا همان (Optimization) را در آخرین مرحله از کامپایل (ترجمه) انجام میدهند، در صورتی که مفسرها عملیات بهینه سازی را در زمان تبدیل انجام میدهند. نکته ۴: سرعت اجرای کدهای کامپایل شده بسیار بیشتر از کدهای تفسیر شده است. برای مثال اگر حلقهای را در نظر داشته باشید که قرار است ۱۰ بار اجرا شود، آن حلقه در حالت مفسر ۱۰ بار تفسیر شده و ۱۰ بار توسط پردازنده اجرا خواهد شد! در حالی که در حال کامپایل شده حلقه یک بار ترجمه میشود و نتیجهٔ آن یک بار توسط پردازنده در زمان نیاز اجرا میشود! این بسیار مهم است و در پردازشهای بسیار بزرگ سرعت برنامههای کامپایل شده به شدت بالاتر از تفسیر شدهها است. نکته ۵: کدهای تولید شده توسط مفسر سطح بالاتری نسبت به کدهای تولید شده توسط کامپایلر دارند در واقع آنها تقریباً قابل خواندن هستند اما کدهای تولید شده توسط کامپایلر غیر قابل خواندن است. نکته ۶: امنیت برنامههای کامپایل شده و همچنین دسترسی به منابع کد آنها از امنیت بیشتری نسبت به برنامههای تحت مفسر دارند. نکته ۷: برنامههای تفسیر شده وابستگی خاصی به سیستمعامل ندارند و در هر جایی که برنامهٔ تفسیر کننده موجود باشد اجرا خواهند شد، در صورتی که برنامههای کامپایل شده برای هر نوع سیستمعامل متفاوت باید مجدداً کامپایل شود که البته برای اجرای آن نیازی به نصب بودن کامپایلر بر روی سیستمعامل نیست. نکته ۸: کامپایلر کد برنامه را به صورت کامل به کُد ماشین ترجمه میکند، بنابراین زمان اجرای آن بسیار کم تر است و انتخاب بسیار خوبی برای دوستداران سرعت است. نکته ۹: استفاده از زبانهای مفسری برای توسعهدهندگان مبتدی آسانتر از نوع کامپایلری میباشد بنابراین یادگیری و استفاده از این نوع زبانها نسبتاً سریعتر و راحتتر از نوع کامپایلری است. فرایند توسعهٔ نرمافزار در این فرایند کامپایلر برنامه را میسازد سپس همه دستورات زبان را از نظر صحت تجزیه و تحلیل میکند و اگر دستوری غلط باشد، اخطار میدهد. در صورتی که خطایی وجود نداشته باشد همهٔ کدها را به کد ماشین تبدیل میکند که در نهایت فایلهای مختلفی را به برنامه اجرایی اضافه میکند و در نهایت برنامه را اجرا میکند. در حالی که مفسر برنامه را میسازد اما، فرایند افزودن فایل اجرایی به برنامه یا تولید کدهای ماشین وجود ندارد بلکه دستورات کد منبع خط به خط در حین زمان اجرا یا به اصطلاح Run-time اجرا میکند. کدام زبان در چه حوزهای کاربرد دارد؟ با توجه به تعاریف بالا نوبت آن رسیده است تا زبان برنامهنویسی مورد نظر خود را بر اساس نیاز و قابلیتهایی که آن در اختیار توسعهدهنده قرار میدهد انتخاب کرد. حوزههای کاربردی زبانهای برنامهنویسی متناسب با کاربرد و رسالت آنها مشخص میشود، به طور کلی زبانهای برنامهنویسی را بهتر است به دو دستهٔ اصلی و فرعی جدا کنیم. در دستهٔ اصلی زبانهایی که پایه و اساس کتابخانهها، نرمافزارهای عظیم، انجینها و همچنین خود زبانهای برنامهنویسی میباشند را زبان مادر و اصلی و تمامی زبانهایی که به عنوانی جهتِ مکمل سازی و یا محصول نوع سوم برای اهداف تجاری ساخته شدهاند را فرعی میگوییم. زبانهای اصلی و مادر: C و ++C زبانهای اصلی و فرعی: Python, Java, Delphi, C#, Swift, Objective-C, Php, Rust, JavaScript زبانهای مکمل رابط کاربری: JavaScript, CSS, Xaml, Xhtml, Html, QML زبانهای مکمل بسترهای بلاکچین: C++, Rust و Solidity درنظر داشته باشید کتابخانهها و برنامههای اساسی و پایه که بخش اعظمی از آنها توسط زبانهای سی++ و سی نوشته میشوند در صورت نیاز برای زبانهای دیگر نیز قابل استفاده هستند. به عنوان مثال سیستمعاملها، نرمافزارهای عظیم، انجینهای بازیسازی، کتابخانههای پرکاربرد و مهم همهٔ آنها توسط زبانهای اصلی توسعه یافتهاند اما در صورت نیاز میتواند از کتابخانههای نوشته شده توسط زبانهای اصلی در زبانهای فرعی نیز استفاده کرد. شاید اینطور به نظر برسد که اگر با زبانهای اصلی هر کاری میتوان انجام داد، پس چرا زبانهای دیگر را مورد استفاده قرار میدهیم؟! جواب سوال این است که زبانهای اصلی و مهم نیاز به دانش بسیار از لحاظ معماری سیستمعامل، کامپایلر و دیگر شاخههای علوم کامپیوتر هستند و نحوِ کُدنویسی در آنها نسبت به زبانهای دیگر مانند جاوا، پایتون، سیشارپ و غیره دشوارتر است. بنابراین ممکن است انتخاب اول برنامهنویسان مبتدی نباشند اما کاربرد آنها جنریک (عمومی) است. اشاره به کاربرد زبانهای محبوب در حوزههای مختلف: توسعهٔ زیرساختها: C, C++, Rust, Go توسعهٔ وبسایت: C++, Java, Php, JavaScript, C#, Ruby, Python توسعهٔ نرمافزارهای موبایل: , C++, Java, C#, Objective-C, Swift, JavaScript, Kotlin توسعهٔ نرمافزارهای دسکتاپ: C/C++, Java, Delphi, VB.Net, C#, JavaScript, Objective-C توسعهٔ نرمافزارهای اِمبِد: C/C++, Python توسعهی بازیهای کامپیوتری: ++C و #C توسعهٔ هوش مصنوعی: C++, Python, R, Prolog, Java, Haskell, AIML توسعهٔ رابطکاربری: JavaScript, QML, XAML نکتهٔ قابل توجهی از کاربرد زبانهای اصلی در این است که خود آنها وابستهٔ زبان برنامهنویسی و محدود بر یک حوزه نیستند و به اصطلاح زبان مادر بشمار میآیند که و در تمامی حوزهها کاربرد دارند. کاربرد در صنایع و حوزههای مختلف بر اساس ویژگیهایی که یک زبان برنامهنویسی ارائه میدهد بسیار مهم است. برای مثال Python, R, Prolog و غیره در حوزهٔ هوش مصنوعی و بیگ دیتا بسیار سادهتر به کمک توسعه دهندگان میآید. در توسعهٔ وبسایت زبانهای برنامهنویسی Node.JS, Php, C#, Asp.Net محبوبیت بیشتری دارند. اما میتوان با توجه به این پست وبسایتهای بسیار سریع و بهینهای را توسعه داد که بی شک نیاز به دانش بسیار بالایی دارد و بهتر است در اهداف خاص از آن استفاده شود. در حوزهٔ موبایل در پلتفرم iOS دو زبان Swift و Objective-C به عنوان زبان اصلی پلتفرمهای iOS, tvOS و watchOS به شمار میآیند. در حوزهٔ اندروید (Android) زبانهای Java و Kotlin به عنوان انتخابهای اول توسعهدهندگان مطرح میشند در صورتی که بسیاری از کتابخانههای اندروید تحت C و ++C توسعه یافته و حتی میتواند با استفاده از ++C اپلیکیشن و بازیهای بسیار سریعتری را تولید کرد. در حوزههای صنایع بازیسازی زبانهایی مانند #C نیز کاربرد دارند، اما ترجیح اول و اصلی در این حوزه بکارگیری ++C است چرا که هیچ زبانی به جز آن نهایت سرعت را ارائه نخواهد داد. آمارها و محبوبیتها سالانه طبق گزارش بسیاری از مراجع نمودارها و آمارهایی در رابطه با ایندکس شدن زبانهای برنامهنویسی ارائه میشود که نمونهای از آنها TIOBE است. متاسفانه باید گفت مقایسهٔ چنین مراجع بر اساس ویژگیهایی که در بالا توضیح دادیم صورت نمیگیرد و صرفاً بر اساس محبوبیت بین کاربران گزارش داده میشوند. برتری زبان نسب به زبان دیگر بر اساس چنین آمارهایی اشتباه بوده و توسط آن نمیتوان یک زبان را به عنوان انتخاب اول در نظر گرفت. همچنین اگر دقت کنید مقایسهٔ زبانهای برنامهنویسی اسکریپتی با کامپایلری و همچنین زبانهایی مانند SQL در بین آنها وجود دارد که از لحاظ منطقی درست نیست چرا که کاربرد زبانها با یکدیگر متفاوت بوده و ملاک آماری این مراجع فقط استقبال کاربران است. تعاریف و هِدایتهای اشتباه به سمت یک زبان برنامهنویسی متاسفانه مشاهده میشود که در بسیاری از گروهها و سایتهای برنامهنویسی چندین زبان برنامهنویسی را به عنوان بهترین انتخاب معرفی میکنند و دلیل انتخاب آنها را مشاهدهٔ رتبههای آن بر اساس ایندکسهای برخی از مراجع و یا طرفداری بعضی از شرکتها و تعصبات بی هدف است! باید در نظر داشته باشید قدرت و ویژگیهای یک زبان ربطی به محبوبیت آن ندارد. اگر احساس میکنید شرکتها تقاضای متخصص زبان برنامهنویسی خاصی را دارد که تکرار میشود به آن معنی نیست که زبانهای برنامهنویسی دیگر در حال منسوخ شدن یا کنار گذاشتن هستند. ارزش زبان ملاک برتری آن است نه محبوبیتش! به عنوان مثال اگر JavaScript رتبهٔ اول از نظر محبوبیت را دارد به آن معنا نیست که Php در حال منسوخ شدن است! هر زبانی کاربرد خودش را نسبت به اهداف و ویژگیهای خود دارد. آیا زبان ماشین منسوخ شده است؟! خیر! این چه سوالیه!!؟ چنین افکار بیهوده را از ذهن خود بیرون بریزید! تمامی زبانهای کامپایلری به جز نوعهای مفسری در نهایت کدهایشان توسط کامپایلر به زبان ماشین یعنی assembly تبدیل میکنند. مثال زیر کد ++C است: int main() { } خروجی آن به زبان ماشین (Assembly) در کامپایلر GCC به صورت زیر خواهد بود: main: push rbp mov rbp, rsp mov eax, 0 pop rbp ret انتخاب چند-سکویی پیشنهاد میشود یا خیر؟ لازم بذکر است که بدانید، ابزارهای چند-سکوی بسیاری وجود دارند که به شما اجازه میدهند بدون داشتن دانش آنچنانی در رابطه با زبانهای برنامهنویسی متعددِ مخصوص سکوهای هدف محصول خود را توسعه دهید. برخی از آنها عبارتند از Xamarin و یا React Native که متاسفانه به دلیل ساختار نامطلوب تبدیل کدهای نوشته شده نتیجهٔ نهایی آنها آنچنان خوب مانند محصولات واقعی زبان بومی نیستند چرا که کدهای آن مستقم به زبان ماشین ترجمه نمیشوند. اما این بسیار مهم است که بدانید ابزارهای بومی چند-سکویی واقعی انتخاب بهتری برای این امر بشمار میآیند که معروفترین آنها Qt است که به صورت بومی بدون اُفت کیفیت محصول نهایی به شما اجازهٔ توسعه محصول در سکوهای مختلف را میدهد که مسلماً دانش بسیار بالایی از سی++ را میطلبد. در نتیجه اگر به دنبال محصول با کیفیت در حوزهٔ چند-سکویی هستید باید دانش بالایی از ++C داشته باشید. نکته: در نظر داشته باشید زبانهای کامپایلری خود به دو دسته نیز تقسیم میشوند که برخی از آنها به صورت مستقیم کدهای نوشته شده را به کد ماشین ترجمه میکنند و برخی از آنها کد نوشته شده را به یک زبان میانی تبدیل و سپس آن را توسط برنامهٔ مجازی برای ماشین برنامهریزی مینمایند. بهتر است توجه داشته آنها مزایا و معایبی نیز خواهند داشت. زبانهای کامپایلری در دو دستهی بومی (Native) و مجازی (Virtual) کامپایل از نوع بومی روشی است که کدهای نوشته شده را به صورت مستقیم به کُد ماشین ترجمه میکند. کامپایل از نوع مجازی روشی است که کدهای نوشته شده را ابتدا به کُدمیانی (کدمشترک یا همان بایت کُد - Byte Code) در جاوا و زبان میانی (CIL) در Net. تبدیل میکند که خودِ آن شبیه به کُد ماشین است. در این فرایند کد مربوطه توسط کامپایلر مخصوص یعنی JIT (کامپایلری از نوع Just-In-Time) در زمان اجرا توسط سیستمعامل، به دستورالعملهای قابل فهم برای پردازنده تفسیر و اجرا میشود (که این فرایند شبیه به فرایند عملکرد اجرایی مفسرها است). زبانهای بومی (زبانهایی که کد آنها به کد ماشین به صورت مستقیم توسط کامپایلر قبل از اجرای آنها توسط سیستمعامل، ترجمه میشوند که به اصطلاح ahead-of-time (جلوتر از زمان) یا همان AOT نام دارد) مانند: C, C++, Rust, Haskell, Clean, Swift, Go, Fortran, D زبانهای مجازی (زبانهایی که کد آنها توسط یک رابط میانی به زبان مشترک ترجمه میشود) : Java و #C مزایا و معایب زبانهای کامپایلری از نوع کلاس بومی (Native) از سرعت بسیار بالایی برخوردار هستند (دلیل آن ترجمهٔ مستقیم کدها به کد ماشین است) در مقابل بزرگترین مزیتی که زبانهای نوع کلاس مجازی (Byte Code) دارند به خاطر وجود یک برنامهٔ واسط جهت شبیهسازی کدهای ترجمه شده به کد قابل فهم برای پردازنده، اجرا شدن آنها در هر پلتفرم بدون کامپایل مجدد امکان پذیر است که البته این ویژگی خود نیازمند نصب بودن JVM بر روی پلتفرم مربوطه میباشد. در نوع بومی برای اجرا در هر پلتفرم لازم است سورس کدها را برای پلتفرم مقصد کامپایل کنید که نیازی به وجود ماشین مجازی مانند JVM یا برنامهٔ خاصی ندارد. سریعترین زبان برنامهنویسی کدام است؟ شاید پاسخ به این سوال به گونهای تعصبی به نظر برسد، اما واقعیت این است که باید حقیقت را پذیرفت! با توجه به دلایلی که به نوع زبانهای کامپایلری آورده شده است مشخص است که سریعترین نوع زبانهای برنامهنویسی باید در دستهٔ شاخهٔ کامپایلری و کلاس Native قرار گرفته باشند چرا که در این مبحث زبانها کامپایلری (مجازی) و مفسری حرفی برای گفتن ندارند. جهت تثبیت آن مستنداتی از بنچمارکها در این بخش آورده شدهاست. حقیقت این است ++C در بدترین حالت ممکن بدون بهینهسازی کدها و فلگهای خاص حداقل ۲ تا ۴ برابر سریعتر از زبانهای کامپایلری دیگر است! تلخترین حقیقت نیز این خواهد بود که ++C حداقل ۱۰۰ تا ۲۰۰ برابر سریعتر از زبانهای مفسری است! با توجه به تجربیات شخصی در صورتی که نوع کامپایلر Clang باشد سرعت کدها به چند برابر از این نیز خواهد رسید! همچنین باید در نظر بگیرید اگر کدهای شما خارج از اصول استاندارد زبان باشد ممکن است نتایج آن به تساوی و حتی پایینترین حالت ممکن برسد. سخن آخر، برای انتخاب زبان برنامهنویسی و به دست آوردن مهارت در آن و در نهایت تبدیل دانش به یک محصول نرمافزاری، بهتر است بر اساس نوع (کامپایلری یا مفسری بودن)، اهمیت سرعت، ویژگیهای آن و کاربردش در حوزههای مختلف تصمیم بگیرید نه بر اساس تعصب و علاقه. دقت کنید که زبانهای برنامهنویسی ابزارهای برنامهنویسی بوده و هرچقدر جعبه ابزار شما کامل باشد توانایی و مهارت شما در توسعهٔ حوزههای مختلف بیشتر خواهد بود. در صورتی که میخواهید در رابطه با انواع روشهای کامپایل و تفاوتهای کامپایل Native، Cross Compile و JIT آشنا شوید، پیشنها میشود مقاله زیر را مطالعه فرمایید.
-
1 امتیازبا سلام و درود، همانطور که میدانید ویژگیهای اخیر در استانداردهای ۱۷ و ۲۰ بسیار عظیم و کاربردی هستند. هدف ما در مرجع آیاواستریم این است که با توجه به بهروزرسانیهای زبان سیپلاسپلاس مهمترین مواردی که نیاز است معرفی کنیم. بنابراین در این بخش به یکی از کاربردیترین موارد مرتبط در استاندارد ۱۷ با عنوان صفتهای ویژه اشاره میشود که در ادامه به تعریف هر یک از آنها میپردازیم. با توجه به استانداردهای ۱۱ و ۱۴ که در آن صفتهایی همچون [[deprecated]] و [[noreturn]] معرفی شدهاند که وظیفهٔ آن به ترتیب نمایش وضعیت منسوخ شدن یک عملکرد و یا وضعیت بازگشتی یک تابع از نوع void است. چنین صفاتی میتوانند در زمان اعلان و تعریف متغیرها و یا توابع مورد استفاده قرار گیرند. به عنوان مثال اگر کدی به صورت زیر داشته باشیم: [[deprecated]] void print(const std::string &message) { std::cout << message << std::endl; } در صورتی که تابع print در بخشی از برنامه مورد استفاده قرار بگیرد، پیغامی از سمت کامپایلر از نوع اخطار (warning) ساطع میشود، مبنی بر آن که تابع مربوطه به عنوان منسوخ شده یاد شده است. warning: 'print' is deprecated این ویژگی میتواند در ساخت و توسعهٔ کتابخانهها، موتورها، چهارچوب (فریمورک) و برنامههایی که قرار است دیگر برنامهنویسان از آنها استفاده کنند بسیار میتواند کاربردی باشد؛ چرا که با اعمال چنین خاصیتهایی در کدهای شما برای توسعهدهندگان یادآوری خواهد شد که کد مربوطه در نسخهٔ جدید یا نسخههای بعدی امکان حذف و یا تغییر را خواهد داشت. #include <iostream> #include <string> [[deprecated]] void print(const std::string &message) { std::cout << message << std::endl; } int main() { print("Hello, World!"); return 0; } در مثال بالا اخطار پیشفرض از سمت کامپایلر ساطع میشود، اما در بعضی از مواقع لازم است پیغام سفارشی جهت راهنمایی بیشتر کاربر اعمال شود که در این صورت صفت میتواند پیغام از نوع رشته را دریافت و در هنگام ساطع شدن، آن را نمایش دهد. برای این کار کافی است متن مورد نظر را به صورت زیر در صفت خود تعیین کنیم. [[deprecated("Use printView with print instead, this function will be removed in the next release")]] برای مثال یک تابع جایگزین و بهینه شده را به صورت زیر در نظر بگیرید، کامپالر اخطار مروبطه و سفارشی شده را نسبت به آن ساطع خواهد کرد. #include <iostream> #include <string> [[deprecated]] void print(const std::string &message) { std::cout << message << std::endl; } void printView(std::string_view message) { std::cout << message << std::endl; } int main() { printView("Hello, World!"); return 0; } همچنین در رابطه با صفت [[noreturn]] که در استاندارد ۱۱ معرفی شده است، باید در نظر داشت این صفت جهت بهینهسازی کامپایلر در رابطه با تولید هشدارهای بهتر و همچنین اعلام اینکه تابع مربوطه قابل دسترسی نیست مورد استفاده قرار میگیرد. مثال: #include <iostream> [[noreturn]] void myFunction() { std::cout << "Hello, World!" << std::endl; throw "error"; } void print() { std::cout << "Print Now!"; } int main() { myFunction(); print(); return 0; } در کد فوق، در زمان همگردانی (کامپایل) پیغام زیر ساطع میشود: warning: code will never be executed بنابراین در زمان اجرا تابع print(); اجرا نخواهد شد، زیرا به عنوان یک کد غیر قابل دسترس بعد از myFunction توسط کامپایلر یاد میشود. چرا که این امر اجازه میدهد تا کامپایلر بهینهسازیهای مختلفی را انجام دهد - نیازی به ذخیرهسازی و بازیابی هرگونه حالتهای ناپایدار در اطراف صدا زننده (Caller) نیست. بنابراین میتواند کدهای غیر قابل دسترس را از بین ببرد. با توجه به نیازهای این چنینی، در استاندارد ۱۷ صفتهای جدیدتر و کاربردیتری نیز ارائه شده است که به معرفی هر یک از آنها در بخش اول از این مقاله میپردازیم. صفتهای معرفی شده در استاندارد 1z یا همان ۱۷ به صورت زیر هستند: [[fallthrough]] [[maybe_unused]] [[nodiscard]] معرفی صفت [[fallthrough]] به طور معمول در برنامهنویسی، هر وقت که مرحلهٔ مربوط به case در دستور switch به انتهای خود میرسد، کد مربوطِ به دستورِ case بعدی اجرا خواهد شد. طبیعتاً عبارت break میتواند از این امر جلوگیری کند. اما از آنجایی که این رفتار را به اصطلاح fall-through میشناسیم، ممکن است در صورت عدم معرفی اشکالاتی را فراهم کند، در این حالت چندین کامپایلر و ابزارهای آنالیز کننده خطای مرتبط به آن را هشدار میدهند تا کاربر در جریان قرار بگیرد. با توجه به این موضوع که ممکن است بعضاً این مورد چشم پوشی شود، در سیپلاسپلاس ۱۷ به بعد یک صفت استاندارد معرفی شد تا توسعهدهنده بتواند با قرار دادن آن در مکان سقوط (fall-through) به کامپایلر اعلام کند که هشداری در آن بخش لازم نیست. کامپایلرها میتوانند هشدارهای مطمئنی را در زمانی که یک عبارت case بدون اجرای دستور break به انتهای خود میرسند و یا سقوط (fall-through) میکند، حداقل با یک جملهٔ مربوطِ به آن را ساطع کند. برای مثال به کد زیر توجه کنید: #include <iostream> int main() { int number { 2017 }; int standard = {0}; switch(number) { case 2011: case 2014: case 2017: std::cout << "Using modern C++" << std::endl; case 1998: case 2003: standard = number; } return 0; } در کد فوق، در زمان اجرای دستور case سوم با مقدار ۲۰۱۷، کامپایلر هشداری به صورت زیر را اعمال خواهد کرد. warning: unannotated fall-through between switch labels در این حالت برای از بین بردن (چشمپوشی کردن) از این خطا در صورتی که نیاز نباشد موارد دیگر مورد بررسی قرار بگیرد قرار دادن دستور break بعد از آن میتواند منطقی باشد. اما با توجه به انتظاری که میرود تا دستورات بدون توقف بین آنها اجرا شود، قراردادن دستور [[fallthrough]]; بعد از آن میتواند راه حل بسیار مناسبی باشد. #include <iostream> int main() { int number { 2017 }; int standard = {0}; switch(number) { case 2011: case 2014: case 2017: std::cout << "Using modern C++" << std::endl; [[fallthrough]]; // > No warning case 1998: case 2003: standard = number; } return 0; } در این حالت، کامپایلر بدون ساطع کردن خطا آن را همگردانی خواهد کرد. معرفی صفت [[maybe_unused]] صفت [[maybe_unused]] برای نشان دادن کد ایجاد شدهای است که ممکن است از منطق قطعی استفاده نکند. این مورد ممکن است اغلب در لینک شدن با پیشپردازندهها مورد استفاده قرار بگیرد یا نگیرد. از آنجایی که کامپایلر (همگردانها) میتوانند نسبت به متغیرهای بلا استفاده هشدار ساطع کنند، این صفت روش بسیار خوبی برای سرکوب آنها خواهد بود. استفاده از این ویژگی میتواند در بخشهای مهمی مفید باشد، فرض کنید کتابخانهای نوشتهایم که قرار است به صورت چند-سکویی دارای ویژگیهای یکسان در بسترهای مختلف باشد. برای مثال ساخت یک فایل در مسیر مشخصی از سیستمعامل مورد نظر جهت اعمال تنظیمات نرمافزار. namespace FileSystem::Configuration { [[maybe_unused]] std::string createWindowsConfigFilePath(const std::string &relativePath); [[maybe_unused]] std::string createMacOSConfigFilePath(const std::string &relativePath); [[maybe_unused]] std::string createLinuxConfigFilePath(const std::string &relativePath); [[maybe_unused]] std::string createiOSConfigFilePath(const std::string &relativePath); [[maybe_unused]] std::string createAndroidConfigFilePath(const std::string &relativePath); } به کد بالا توجه کنید، در صورتی که شما در محیط کدنویسی در حال استفاده از یک دستور مورد نظر از بین دستورات بالا هستید، طبیعتاً کامپایلر به بقیهٔ دستوراتی که از آنها استفاده نمیکنید پیغامی مبنی بر آن که دستور مربوطه بلااستفاده مانده است را ساطع میکند. جهت جلوگیری از این هشدارها کافی است صفت [[maybe_unused]] را قبل از آنها اعمال کنید. معرفی صفت [[nodiscard]] در صورتی که از [[nodiscard]] استفاده شود، کامپایلر میتواند درک کند توابعی که مقدار بازگشتی دارند نمیتوانند مقدار بازگشت داده شدهٔ آنها را دور انداخت و یا از آنها در زمان صدا زدن صرف نظر کرد. بنابراین با تعریف این صفت در توابع از نوع بازگشتی میتوان پیغامی به صورت زیر را ساطع کند. مثال: #include <iostream> [[nodiscard]] int myFunction() { return 17; } int main() { myFunction(); return 0; } در مثال فوق تابع myFunction در زمان فراخوانی که مقدار بازگشتی آن بی نتیجه مانده است از سمت کامپایلر هشدار مورد نظر را دریافت خواهد کرد. این پیغام در صورتی که مقدار بازگشتی تابع به متغیری از هم نوعِ خودش ارسال شود، ساطع نخواهد شد. #include <iostream> [[nodiscard]] int myFunction() { return 17; } int main() { int func; func = myFunction(); return 0; }
-
1 امتیازبا سلام، طبق بررسیهای لازم تغییراتی در گروههای کاربری اعمال شده است که از این پس کاربرانی که به عنوان کاربران فعال در حوزهٔ یادگیری و مشارکت در بحثها فعال میکنند از گروه پیشفرض کاربران عادی به کاربران رسمی تغییر دسترسی خواهند داشت. طبق آخرین اصلاحیه در سند( شرایط کسب مجوز فعالیتی و ارتقا حسابکاربری) ، کاربران عضو در این گروه دسترسی لازم برای ارسال تصویر، افزودن امضاء و همچنین عدم نیاز به تایید مطالب توسط مدیریت را خواهند داشت.
-
1 امتیازدرود بر شما؛ برای اینکار میتوانید شما از QScrollArea استفاده کنید. این کلاس یک منطقهٔنمایش Widgetها و یک QScrollBar را به شما میدهد، و شئ را که میخواهید Scroll کنید را باید به عنوان Child Widget به آن معرفی کنید. برای مثال : #include <QApplication> #include <QDialog> #include <QGroupBox> #include <QList> #include <QScrollArea> #include <QTextEdit> #include <QVBoxLayout> int main(int argc, char** argv) { QApplication application(argc, argv); QDialog dialog; QVBoxLayout layout; QScrollArea scroll(&dialog); QGroupBox groupedArea; QList<QTextEdit*> widgets; for (int i {}; i < 20; ++i) { widgets.append(new QTextEdit); layout.addWidget(widgets.at(i)); } scroll.setWidget(&groupedArea); scroll.setWidgetResizable(true); groupedArea.setLayout(&layout); dialog.show(); return application.exec(); } دقّت کنید که باید حتماً تابع setWidgetResizable را با مقدار true برای تغییر اندازهٔ مناسب Widget فراخوانی کنید. خروجی حاصل از کد بالا : با تشکر از آقایرضوی.
-
1 امتیازبرنامهنویس تنها در این عنوان خلاصه نمیشود و لازم است بدانید که برنامهنویسان در چند دسته متفاوت وجود دارند که برخی از آن ها به صورت Back-End و برخی Front-End فعالیت میکنند. در کل به کسانی که توانایی برنامهنویس در بخش Back-End را دارند به آنها Back-End Developer میگویند. همچنین برنامهنویسانی که توانایی توسعه در بخش طراحی رابطکاربری و تجربهکاربری را با عنوان Front-End دارند Front-End Developer میگویند. در نظر داشته باشید که توسعهدهندگان و طراحان بخش تجربهکاربری (UX) و رابطکاربری (UI) خود وظایفی در سمت طراحی یک محصول را دارند که به خودی خود میتوانند به عنوان توسعهدهندهی فرانتاِند محسوب شوند اما ممکن است زمینهی اجرایی آنها با محیطهای توسعه که شامل کدنویسی هستند نباشد! بنابراین شاخهای از حوزهی توسعه در نرمافزار کامپیوتر وجود دارد که میتواند با ترکیب دانش طراحی و کدنویسی و تسلط کامل بر این دو حوزه به صورت ترکیبی با دانش و توانایی بسیار بالا عنوان شود که به آن فولاِستک میگویند. البته فولاِستک ابعاد مختلفِ خود را دارد، برای مثال ممکن است یک توسعهدهندهی فولاِستک تنها در پلتفرم اندروید توانایی طراحی و کدنویسی را به صورت همزمان و بدون نیاز به یار تیمی خود داشته باشد. اما در اصل توسعهدهندههای با تجربه با سابقهی بالا که توانایی مدیریتی پروژه و توسعهی آنها را دارند از نوع فولاِستک تمام عیار محسوب میشوند که در ادامه به ویژگیهای آنها اشاره شده است. یک برنامهنویس حرفهای یا همان فولاِستک میبایست مهارتهای زیر را داشته باشد: مسلط به زبانهای برنامهنویسی پایه آشنایی با UX و UI و مباحث مرتبط با هر یک از آنها مدیریت پروژه بر روی پلتفرمهای مختلف توانایی کنترل کیفیت محصول توانایی کار با انواع فناوریها و کتابخانهها توانایی کار با انواع دیتابیس و مدیریت آنها هک و امنیت بهینه سازی موتورهای جستجو آشنایی و توانایی درک و مدیریت کامپایلرها و مفسرها درک نیازهای کاربران در محصول (UX) آشنایی با سیستم عاملهای مختلف آشنایی و توانایی تولید محصول به صورت چند-سکویی (Cross-Platform) آشنایی با شبکه و پیکربندی آن برای محصول آشنایی با مدیریت سرور و هاستینگ آشنایی با سیستمهای مدیریتی و مجازی مانند VM آشنایی با سخت افزار آشنایی با رابط های برنامه نویسی APIها آشنایی با انواع محیطهای توسعه و موارد دیگر که در یک پروژه از صفر تا صد میتوان به آنها نیاز پیدا کرد. برنامهنویسان Full-Stack Developer به تنهایی میتواند درتولید و توسعه یک محصول موثر باشد و زمانی که با مشکلی مواجه شوند نمیگوید من آن را بلد نیستم، بلکه حتماً آن را حل خواهند کرد. به طور کلی کسب مهارت در سطح بالا در حد یک توسعه دهنده فولاِستک بسیار سخت است اما نباید بگوییم که غیر ممکن است، در صورتی که چنین تعریفی برای یک توسعهدهندهی فولاستک در نظر بگیریم، بدون اغراق باید گفت تعداد اندکی از این برنامهنویسان موجود است که بتوانیم چنین لقبی را به آنها اختصاص بدهیم بنابراین چنین برنامهنویسانی بسیار ارزشمند هستند لذا به خوبی میدانند یک نرم افزار چگونه طراحی میشود و توانایی این را دارند از صفر تا صد یک نرمافزار را طراحی و روانه بازار کنند. علاوه بر این توسعه دهنده Full-Stack کسی است که واژگانی مانند نبود، نمیشه، امکان نداره، نمیتوم، کار من نیست و ... را بر زبان نمیآورند و اگر هم چیزی را ندانند تمام تلاش خود را میکنند تا بدون نیاز به کمک شخصی دیگر آن را حل کنند. این نوع توسعهدهندهها بسیار با ارزش و مهم هستند، و نکته جالب اینجاست که آنها سالها تلاش کردهاند و مسلماً به تنهایی صاحب کسبوکار خود بوده و در انتخاب اول برای کسی کار نمیکنند. برای توسعه دهندهی فولاِستک فرقی نمیکند محصول تحت چه پلتفرمی باشد، او میتواند تحت دسکتاپ، وب، موبایل و دیگر پلتفرم ها آن را تولید کند.
-
1 امتیازروش دیگه برای ادد کردن کتابخانه رو هم امتحان کردم اوکی شد: یک پوشه ایجاد کنید مثلا در مسیر C:\Qt\lib-archive مرحله بعد در داخل همین پوشه lib-archive برای راحتی میتوانید دو پوشه به نام های include و lib ایجاد کنید. در این مرحله باید فایل های .h از کتابخانه اصلی را در پوشه include کپی کنید و همچنین فایل بیلد شده از dll ها ( یا پسوند .a ) را در پوشه lib کپی کنید. به Qt رفته و یک پروژه ایجاد کنید و در داخل فایل .pro به صورت دستی کد زیر را اضافه کنید: INCLUDEPATH += "C:/Qt/lib-archive/include" LIBS += -L "C:/Qt/lib-archive/lib" LIBS += -llibarchive اکنون تغییرات فایل .pro را ذخیره کرده و پروژه را یک بار بیلد کنید، کار تمام است و برای آزمایش میتوانید طبق مثال های کتابخانه عمل کنید. با تشکر فراوان از اساتید محترم بخصوص آقای @کامبیز اسدزاده ?
-
1 امتیازبا این تکه کد حل شد QByteArray ba; ba.resize(100); ba.fill(0x00); ba[0] = 0x01; port->write(ba); port->flush();
-
1 امتیازبا سلام، در این پست ما قصد داریم در رابطه با نحوهٔ آغاز یادگیری کیوت توضیح دهیم. اینکه به عنوان یک تازهکار چه پیشنیازاتی را باید مطالعه و در نهایت چگونه و تحتِ چه منابعی این کتابخانهٔ قدرتمند را بیاموزیم. همچنین پاسخ برخی از سوالات شما را در این پُست به طور شفاف ارائه شده است که طیِ چندین سال سوال علاقه مندان بودهاند. معرفی سریع و سادهٔ کیوت (Qt) این ابزار (به انگلیسی: Qt) با آوای «Cute» به فارسی (کیوت) مجموعهای از کتابخانهها و سرآیندهای نوشتهشده به زبان سی++ است که به برنامهنویس امکان توسعه آسان نرمافزارهای کاربردی را میدهد. کیوت شامل چندین کلاس برای کار با واسط گرافیکی، چندرسانه، ابزارهای پایگاهداده، شبکه و … است. نرمافزارهای نوشته شده با ابزار کیوت قادرند تا با استفاده از یک کامپایلر زبان سیپلاسپلاس برای طیف وسیعی از سیستمعاملها از جمله گنو/لینوکس (نسخههای رومیزی و وسیلههای قابل حمل)، ویندوز، ویندوز CE، مکاواس و … همگردانی شوند. بدین ترتیب حمل نرمافزار نوشته شده بدون تغییر در متن کد نوشته شده امکانپذیر است. از کیوت در زبانهای برنامهنویسی متعددی مانند سی++ و جاوا و پایتون میتوان استفادهکرد. پیشنیازات برای یادگیری کتابخانه Qt دانش متوسط و به بالا در رابطه با زبان برنامهنویسی مُدرن سیپلاسپلاس نسخههای ۱۱ به بعد، (بنابراین اگر شما هیچ اطلاعی در رابطه با ساختار برنامههای سیپلاسپلاس و نحوهٔ عملکرد آن ندارید، شانس موفقیت شما بسیار پایین خواهد بود و ممکن است برنامهٔ تولید شدهٔ شما به بدترین شکل ممکن پیاده سازی شود و حتی مدام دست به کمک دیگران باشید). من پیشنهاد میکنم قبل از آن با زبان سیپلاسپلاس آشنا شوید. آشنایی با کامپایلر و نحوهٔ عملکرد آن در پلتفرمهای مختلف از جمله ویندوز، مکاواِس، لینوکس، اندروید و آیاواِس. مهم است بدانید تسلط کافی در زبان سی++ و ساختار برنامههای نوشته شده در این زبان بسیار موثر است. آشنایی و تسلط کافی به ابزارهای ساخت و ساز مانند CMake یا QMake و QBS. آشنایی با معماریهای مختلف مانند x86، x86-64، Arm و غیره... و پیکربندی پروژه و تهیهٔ خروجی. آشنایی با معماریِ سیستمعاملها، برخی از رابطهای برنامهنویسی (Api)، برای مثال اگر قرار است از خاصیت چند-سکویی کیوت استفاده کنید تا یک برنامهٔ تحت اندروید را توسعه دهید، در این صورت باید در نظر داشته باشید که همه چیز توسط کیوت حاضر و آماده نیست، شما بدون درکِ معماری سیستمعامل اندروید و پیکربندی برنامه در مراحل توسعه نمیتوانید به راحتی از پسِ این کار بر آیید و هر از گاهی نیاز است به شیوهٔ اختصاصی پلتفرم مورد نظر برنامهٔ خود را توسعه دهید. در پلتفرمهای اپل نیز تسلط کافی به Xcode و مدیریت حساب توسعه در Apple Developer مورد نیاز است، شما باید بدانید چطور یک پروفایل را برای پلتفرم آیاواس باید تنظیم کنید. اگر شما در پلتفرمهای مختلف کار میکنید، قطعاً نیاز به کار با کیتهای توسعه، رابطهای توسعه و همچنین ابزارهای ساخت هر پلتفرم خواهید داشت. بنابراین، در محیط ویندوز نیاز دارید محیط خود را با ابزارهای ساخت و ساز آن مانند Microsoft Visual Studio Build Tools که شامل کامپایلرها، دیباگر و برخی از ابزارهای برنامهنویسی است هماهنگ کنید، چرا که بدون آن امکان توسعه وجود ندارد (نیاز نیست نرمافزار محیط توسعهٔ یکپارچهٔ Visual Studio را نصب کنید، همان ابزار Build Tools کافی است). در محیط لینوکس نصب پیشنیازها و کامپایلرهای GCC و یا Clang مهم است و در مک نیز بهروز رسانی و نصب ابزارهای ساخت و ساز و همچنین نسخهٔ کامل Xcode از واجبات توسعه در کیوت خواهد بود. بنابراین داشتن تجربه و آشنایی کافی با این ابزارها متوسط به بالا به نفع شماست. آشنایی با اصطلاحات و مفاهیم تجربهکاربری و رابطکاربری جهت طراحی مناسب با فناوریهای Qt Widget و Qt Quick (در صورتی که علاقهمند به طراحی ظاهر برنامههای خلاقانه دارید). آشنایی Xml برای سبک سنتی و ویجت و JavaScript پیشنیاز خوبی برای درک مسائل مربوط به فناوری طراحی در کیوتکوئیک است که تحت QML رابطهای کاربری و اجزای مختلف و خلاقانه را پیاده سازی خواهید کرد. توجه کنید که مستندات کیوت به اندازهٔ کافی جهت آشنایی با پیشنیازات بهروز رسانی میشود و نسبت به نسخههای ۵ و حتی ۶ توضیحات لازم را ارائه میکند. با توجه به این مسائل، مراحل نصب و داشتن حساب کاربری در کیوت لازم است، اما به این معنا هم نیست که شما از نسخهٔ رایگان نمیتوانید استفاده کنید، توجه داشته باشید که تنها تفاوت بین نسخهٔ رایگان و تجاری در یک سری ویژگیهای اختصاصی شرکت کیوت است که در پشتیبانی از آنها اعمال شده و نه بیشتر. آیا کیوت یک زبان برنامهنویسی است؟ چرا نحوِ (Syntax) آن با سیپلاسپلاس استاندارد فرق میکند؟ خیر، کیوت ابتدا به عنوان یک کتابخانهٔ رابط گرافیکی کاربر توسعه داده شده است که بعدها برای توسعه اهدافِ بیشتری شامل کتابخانههای شبکه و غیره شده است که در قالب یک چهارچوب (فریموُرک) که تحت زبان برنامهنویسی سیپلاسپلاس برای این زبان توسعه یافته است و در زمینههای مختلفی کاربردهای فراوان دارد. دلیل زیبایی و ظاهر سادهٔ آن ساختار بسیار قدرتمند آن است که موجب شده همانند چهارچوبهای قدرتمند دیگری خودنمایی کند. (اما قول این ظاهر و سادگی آن را نخورید، چون با سیپلاسپلاس طرف هستیم) آیا کیوت از سرویسها و قابلیتهای اختصاصیِ اپلیکیشنهای اندروید و آیاواِس را به طور کامل پشتیبانی میکند؟ به صورت پیشفرض خیر، هیچ ابزاری به صورت چند-سکویی فعلاً (تاکید میکنیم - فعلاً تا به این تاریخ) وجود ندارد که تمامی امکانات اختصاصی این پلتفرمها را بدون کد نویسی اختصاصی پشتیبانی کند. اما این به این معنی نیست که جواب منفی خواهد بود، لذا شما در برنامهنویسی سیپلاسپلاس به راحتی میتوانید برای پلتفرمهای فوق با سرویسهای آنها ارتباط برقرار کنید. این کار کمی نیاز به دانش فنی بالایی خواهد داشت! برای مثال (دسترسی به سرویسهای اندروید یا آیاواس) با ترکیب کُدهای آبجکتیو-سی و جاوا امکانپذیر است و یا باید با توجه به SDKهای پلتفرمهای مورد نظر آنها را سفارشی نویسی کنید. این کار به راحتی قابل انجام خواهد بود و کافی است شما در رابطه با نحوهٔ ترکیب کُدهای آن آشنا باشید. کیفیت خروجی برنامههای تحت کیوت چگونه است؟ اگر شما واقعاً یک برنامهنویسِ ماهرِ سیپلاسپلاس باشید میتوانید برنامهای را تولید کنید که بسیار خوش دستتر و سریعتر از برنامههای پیشفرضِ پلتفرمها باشد. در بارهٔ دلایل آن به ساختار برنامههای نوشته شده توسط این زبان به این مقاله مراجعه کنید. اگر غیر از این باشد برنامهٔ شما بسیار بد و کُند عمل خواهد کرد و بهتر است سراغ زبانهای پیشنهادی (هر پلتفرم) بروید. هرچند سیپلاسپلاس یک زبان بومی برای تمامی پلتفرمها محسوب میشود اما این ریسک برای افراد مبتدی پیشنهاد نمیشود. معمولاً برنامههای گسترده و عظیم توسط سیپلاسپلاس توسعه داده میشوند که برنامهنویسان آن واقعا حرفهای و با قوانین این زبان آشنا هستند. آیا برای تولید برنامههای مک و آیاواس نیاز به سیستم خاصی داریم؟ بله، شما بدون وجود سیستمعامل مک نمیتوانید برنامهای را بر روی دستگاههای اپِل کامپایل کنید. این امر مستلزمِ سیستم عامل اختصاصی این شرکت بوده و باید توسعه دهنده دارای حساب کاربری معتبر سالانه باشد تا بتواند برنامهٔ خود را بر روی دستگاههای مورد نظر اجرا کند. در غیر این صورت تنها میتواند برنامهٔ خود را بر روی سیستم خود مورد آزمایش و خطا قرار دهد. آیا کیوت در ایران بازار کار مناسبی دارد، آیا ارزش دارد من این کتابخانه را یاد بگیرم؟ خوشبختانه کیوت بیشتر از ۲۰ سال است که در دنیا مورد استفاده قرار میگیرد و کشورهای پیشرفته از آن استقبال میکنند. در کشور ما مدتی است این کتابخانه مورد استقبال قرار گرفته و بسیاری از شرکتها مایل به ساخت و توسعهٔ برنامههای خود تحت این کتابخانه هستند که برخی از دلایل آن (بهره بردن از قابلیتهای زبان سی و سیپلاسپلاس و ویژگیهای خاص آن است). از طرفی کیوت به عنوان یک کتابخانهٔ چندسکویی، مناسب برای تولید و توسعهٔ محصولات در قالب اپلیکیشنهای موبایل و برنامههای کاربردی بر روی دسکتاپ است که در نوع خود کم نظیر است. استفاده از این کتابخانه، موجب سهولت و افزایش سرعت توسعهٔ تولید و طراحی نرمافزار میشود و شما میتوانید با توجه به حفظ کیفی کدهای خود از یک محیط مجهز به ابزارهای طراحی پیشرفته استفاده کنید. پشتیبانی بسیار خوب از زبان فارسی و به خصوص تاریخ شمسی و دیگر موارد، طراحی به شیوهٔ استاندارد راست به چپ و رعایت اصول در آن یکی از دلایلی است که میتوان تضمین کرد کیوت یک ابزار مناسب در طراحی و توسعهٔ برنامههای بومی به زبان فارسی است. چه کسانی یا شرکتهایی از این فریمورک استفاده میکنند؟ جالب است بدانید کتابخانهٔ کیوت محدود به فرد یا شرکت خاصی نیست، با توجه به دو نسخهٔ تجاری و رایگان آن، شرکتهای خصوصی، افراد و توسعهدهندگان بسیار هستند که از آن به عنوان یک فریمورک طراحی و تولید برنامه استفاده میکنند. معمولاً شرکتهای توسعهدهندهٔ تجهیزات سختافزاری، پزشکی، رباتیک، صنعتی و دیگر موارد از آن استفاده میکنند. همچنین بازار طراحی نرمافزارهای هوشمند موبایل، نرمافزارهای کاربردی و پرکاربرد از این کتابخانه استفاده میکنند. اما تبلیغات در این زمینه به دلیل عدم شناخت، تسلط و آشنایی به سی++ نسبت به دیگر ابزارها کمتر است. درآمد و هزینههایی که میتوان از انجام پروژههای کیوت دریافت کرد چگونه است؟ به طور کلی نمیتوان در مورد یک تعرفهٔ مشخص صحبت کرد، این بستگی به نوع مهارت شخصی و کیفیت کار دارد. اما در این مقاله میتوان به این اشاره کرد که برنامهنویسی سی++ و کیوت یکی از خوش درآمدترین مباحثی هستند که میتوان به آن اشاره کرد که البته بستگی به مهارت و تسلط کافی توسعهدهنده دارد. آیا کیوت از سکوی وِب پشتیبانی میکند؟ کیوت از تمامی پلتفرمها پشتیبانی میکند، مخصوصاً با پشتیبانی از ماژولهای QtWebEngine و QtWebAssembly این امر امکانپذیر است که برنامههای خود را تحت فناوریهای وِب نیز توسعه دهید. آیا من حتماً باید به زبان سیپلاسپلاس مسلط باشم؟ هرچند زبان سی++ یکی از الزامات کیوت است، اما همانطور که اشاره شد، آشنایی با هسته، کتابخانهٔ پیشفرض، سینتکس و روشهای برنامهنویسی رایج آن برای درکِ بهتر کیوت مهم هستند. من دانشجو یا متخصص رشتهٔ کامپیوتر نیستم، آیا میتوانم این کتابخانه را یاد گرفته و از آن در توسعه برنامههای مورد نظر خود استفاده کنم؟ بله، اما ممکن است در تجزیه و تحلیل رفتارهای سیستمعامل، مدیریت خطاها و پیکربندی ابزارهای تخصصی (برنامهنویسی) با مشکلاتی مواجه شوید که تنها متخصصات این رشته میتوانند آن را درک و حل کنند. آیا واقعاً حجم برنامههای کیوت نسبت به Net. یا Java بیشتر است !؟ خیر، به طور ذاتی برنامههای توسعه داده شده توسط سی++ دارای کمترین حجم برنامه هستند، معمولاً کتابخانههای استاندارد این زبان به صورت پیشفرض بر روی سیستم عاملها تعبیه شده و در دسترس قرار دارند. اما شما در ویندوز زمانی که با داتنت برنامهنویسی میکنید، فریمورک مربوطه از قبل بر روی سیستم عامل ویندوز نصب بوده و بدون آن هیچ برنامهٔ نوشته شده توسط داتنِت قابل اجرا نمیباشد. اما چون از قبل این کتابخانه بر روی سیستمعامل تعبیه شده است شما نیاز به تنها داشتن فایل اجرایی دارید و نیازی نیست فریمورک داتنت را در کنار فایل اجرایی خود مستقر کنید. بنابراین حجم مربوط به چهارچوب به چشم نیامده و اینطور به نظر میرسد که برنامههای تحت دات نت بسیار سبُکتر هستند! متاسفانه این تفکری اشتباه است برنامههای تحت سیپلاسپلاس نسبت به زبانهای دیگر کم حجمتر و سبُکتر بوده و شما کافی است فایلهای مربوط به کتابخانه را در کنار برنامهٔ خود داشته باشید. در رابطه با کتابخانهٔ Qt نیز باید گفت کیوت به عنوان یک چهارچوب مانند دات نت شامل کلاسها و ماژولهایی است که باید همانند دات نت بر روی سیستم عامل تعبیه شود اما چون اینکار به صورت جداگانه در کنار برنامهٔ شما قرار میگیرد اینگونه تصور میشود که برنامههای مبتنی بر کیوت نسبت به دات نت از حجم بیشتری برخوردار هستند. این کاملاً طبیعی بوده و به عنوان نکته ضعف نیست. من علاقهٔ خاصی به سیپلاسپلاس دارم و میخواهم کیوت را یاد بگیرم، از کجا و چه تحت منابعی باید شروع کنم؟ خوشبختانه کیوت از لحاظ مستندات بسیار جامع است و شما میتوانید از این آدرس به تمامی مستندات مورد نیاز خود دسترسی داشته باشید. همچنین اگر نگران اینترنت خود هستید و یا به آن دسترسی مداوم ندارید میتوانید از داخل محیط توسعهٔ کیوت کریتور از بخش Help آن مستندات مورد نیاز خود را به صورت آفلاین دریافت کنید. من دنبال کتاب آموزشی کیوت هستم، آیا کیوت کتابهای آموزشی مفیدی در این زمینه از مقدمه تا پیشرفته دارد؟ بله، در این بخش شما میتوانید کتابهایی را در این زمینه مشاهده کنید که مرجع رسمیِ کیوت آنها را تایید کرده است. من به زبان انگلیسی تسلط کافی ندارم، ترجیح میدهم که از مراجع فارسی معتبر استفاده کنم، آیا کیوت در این زمینه منابعی دارد که معتبر باشند؟ خوشبختانه کیوت به قدری طعمِ جذابی برای برنامهنویسی دارد که دو کتاب مقدماتی و پیشرفتهٔ این کتابخانه به زبان فارسی نوشته و در کتابخانهٔ ملی کشور به صورت رسمی به ثبت رسیدهاند و عبارتند از نسخههای مقدماتی برای Qt Widgets و نسخهٔ پیشرفته برای Qt Quick (این کتابها تجاری هستند) که در لیست کتابخانهٔ اصلی کیوت نیز تأیید و ثبت شدهاند. آیا مقالات یا کتابهای آموزشی رایگانی هم برای کیوت وجود دارد؟ تنها مرجع آموزشی که در این رابطه به زبان فارسی توضیح میدهد، آیاواستریم است، تقریباً هیچ مقاله یا کتاب جامع و کاملی به صورت رسمی به زبان فارسی خارج از مرجع آیاواستریم (به رایگان) وجود ندارد. اما وعدههایی میدهیم که در پلتفرم فانوکس آموزشهای جدی و با ارزشی برای کیوت ارائه شود که در دو هدف رایگان و تجاری برنامهریزی شدهاند. آیا لیستی برای مشاهدهٔ برنامههای توسعه یافته توسط Qt داریم؟ بسیاری از برنامههای قدرتمند و خارقالعادهای توسط سیپلاسپلاس توسعه داده میشوند که میتوان لیست عظیمی از آنها را نام برد. اما در این میان لیستی از برنامههایی که تحت کیوت توسعه داده شدهاند در این بخش آمده است. برای یادگیری استاندارد سیپلاسپلاس و تقویت مهارت خود در این زبان کدام مقالات و کتابها را پیشنهاد میکنید؟ علاوه بر این که شما میتوانید در مرجع به دنبال آموزشهای مرتبط با این زبان باشید، پیشنهاد ما این است که از مراجع رسمی آن نیز استفاده کنید. برخی از آنها به صورت زیر آمدهاند: cppreference.com http://www.cplusplus.com/ Learn C++ C++ Tutorial | SoloLearn: Learn to code for FREE! Learn C++ (Introduction and Tutorials to C++ Programming) Qt Documents Qt Quick & QML اگر سوالی داشته باشم کجا میتوانم آن را مطرح کرده و به پاسخ خود برسم؟ شما میتوانید برای سوال و پرسش در انجمنهای این مرجع اقدام کنید. اساتید و دوستان با تجربه سوالات شما را دریافت و مناسبترین پاسخها را ارائه خواهند داد. همچنین شما میتوانید ما را در گروه سیپلاسپلاس و کانال تلگرامی دنبال کنید. نکته (در این پُست بنابر اهداف فرهنگسازی برای حق چاپ) فایلهای مرتبط با کتابهای آموزشی زبان اصل و یا زبان فارسی قرار داده نشده است. کتابهای زیادی در رابطه با این زبان وجود دارند که به زبان اصلی میباشند اما برای احترام به نویسندهٔ آنها از ارسال چنین فایلهایی معذوریم. این پُست ممکن است ویرایش یا بهروز رسانی شود.
-
1 امتیازدر این پُست قصد دارم در رابطه با نحوهٔ نصب و اجرای برنامههای تحت کیوت تحت موارد زیر را توضیح دهم. راهنمای فرایند نصب و استقرار برنامه بر روی پلتفرم Windows راهنمای فرایند نصب و استقرار برنامه بر روی پلتفرم macOS راهنمای فرایند نصب و استقرار برنامه بر روی پلتفرم Linux راهنمای فرایند نصب و استقرار برنامه بر روی پلتفرم Android راهنمای فرایند نصب و استقرار برنامه بر روی پلتفرم iOS قبل از هر چیز لازم است بدانید که برای نصب و راه اندازیِ برنامههای نوشته شده تحتِ سیپلاسپلاس و کتابخانههایِ آن باید پیشنیازات آنها درقالب فایلهایی از کتابخانه در کنار برنامه قرار بگیرد. راهنمای فرایند نصب و استقرار برنامه بر روی پلتفرم Windows در این محیط نسبت به نوع و نسخهٔ Qt و کامپایلری که مورد استفاده قرار گرفته است باید توجه داشته باشیم که هنگام کامپایلر و خروجی گرفتن متناسب با سیستم مقصد آن را تهیه کنیم، برای مثال نوع معماری یعنی x64 یا x86 بودن یک سیستم بسیار مهم است. مواردی که باید به آنها هنگام کامپایل توجه کنیم: مشخص سازی نوع کامپایل برنامه حالت یا همان Mode ای که برنامه روی آن ساخته میشود، اگر برنامه بر روی Debug ساخته میشود تمامی موارد بعدی بر اساس دیباگ تعیین و در غیر اینصورت بر اساس نوع Release مشخص خواهند شد. نوع معماری خروجی در برنامه، باید توجه داشته باشید برنامههای 32 بیتی توسط کامپایلرهای x86 یا 32 بیتی تهیه میشوند و برنامههای 64 بیتی توسط کامپایلر های x64 که خود نیازمند سیستم و بستر برنامهنویسی میباشند که 64 بیتی هستند، یعنی اگر نیاز باشد برنامه شما 64 بیتی کامپایل شود ابتدا باید سیستم عامل و نسخه کامپایلر محیط توسعه از آن پشتیبانی کند. انواع ماژولهای استفاده شده در کتابخانه Qt مهم است، به عنوان مثال در حالت عادی ماژول Qt5Core نیاز است ولی اگر در پروژه شما از ماژولهای دیگری مانند Network استفاده شده باشد در این حالت نیاز خواهید داشت فایل یا ماژول مربوط به آن را وارد برنامه کنید که شامل Qt5Network میباشد که لیست کاملی از ماژولها را بر اساس نیاز در ادامه مشخص خواهیم کرد که بر چه اساسی چه نوع ماژول و چه فایلی باید همراه برنامه موجود باشد. شروع کامپایل و گسترش برنامه: معمولاً نسخه های آزمایشی یک محصول در حالت Debug جهت بررسی و آنالیز خطاهای موجود در آن میباشد که توسط تیم توسعهدهنده یا افرادی که میتوانند در باگ گیری آن همیاری نمایند استفاده خواهند کرد، بنابراین بر فرض اینکه ما قرار است یک نسخه استاندارد و نهایی از محصول را در اختیار کاربر قرار دهیم از حالت Release استفاده خواهیم کرد. در بخش Projects میتوان نوع کامپایلر و مسیر خروجی از آن را مشخص کرد، دقت کنید که در این بخش قسمت Build بر روی حالت Release باشد، در این مثال ما از کامپایلر MSVC2017 و نسخه ۶۴ بیتی آن استفاده کردهایم که مسیر خروجی آن مشخص است. همانند مک و لینوکس در ویندوز نیز ابزاری با نام windeployqt وجود دارد که در مسیر QTDIR/bin/windeployqt میباشد. توسط این ابزار میتوان برنامه را در قالب یک پکیج جمع آوری و مستقر ساخت. برای مثال ما برنامه ای ساخته ایم که در مسیر مورد نظر MyAppRoot//C:/Users/Compez/Desktop میباشد. با دستور cd به مسیر فوق خواهیم رفت: cd C:/Qt/Qt5.11.0/5.11/msvc2017_64/MyAppRoot البته قرار است در این مسیر خروجی فایل بعد از کامپایل ایجاد شود که با غیر فعال سازی امکان Shadow Build این ممکن خواهد شد که فایل مربوطه در مسیر ریشه برنامه ایجاد شود. با فرض اینکه بعد از کامپایل فایل MyApplication.app در مسیر ذکر شده موجود باشد دستور زیر را در ترمینال وارد خواهیم کرد: C:/Qt/Qt5.11.0/5.11/msvc2017_64/bin/windeployqt MyApplication.exe دقت کنید که اگر نیاز باشد با استفاده از گزینههای موجود در ابزار برنامه خود را مستقر سازید کافی است دستور ایجاد را به صورت زیر وارد کنید: C:/Qt/Qt5.11.0/5.11/msvc2017_64/bin/windeployqt MyApplication.app –verbose=3 –no-plugins در ویندوز بر خلاف ایستگاههای یونیکس فراهم آوردن تمامی فایلها در کنار برنامه صورت خواهد گرفت. اما بعد از اجرای دستور فوق برنامه به تنهایی قابل اجرا نخواهد٬ لذا فایلهای msvcp140.dll و vcruntime140.dl نیاز هستند تا در کنار برنامه قرار گیرند. این فایلها در تمامی نرمافزار های بزرگ در کنار برنامه موجود هستند مگر اینکه به صورت جدا پکیج مربوط به آن را نصب کنید که توصیه نمیشود. توجه داشته باشید که فایلهایی که قبل از پسوند .dll آخر حرف آنها به d ختم میشود نشانگر آن است که مربوط به نسخه دیباگ هستند. در صورتی که در حالت Release برنامه خود را کامپایل میکنید فایلهایی را در کنار برنامه خود قرار دهید که حرف آخر آنها به d ختم نشده باشد. برای مثال فایل QtCored.dll مخصوص نسخه دیباگ بوده و فایل QtCore.dll مخصوص نسخه ریلیز. بعد از کامپایل برنامه و اجرای خروجی آن در ویندوزی که بر روی آن Qt و سیپلاسپلاس نصب نیست مسلما با خطاهای زیر مواجه خواهیم شد: خطاهای فوق بیانگر این است که فایلهای فوق در کنار پروژه یا در هسته سیستم عامل پوشه windows/system32 و یا windows/SysWow64 نصب نشده است که در ادامه برای حل این خطا راهکار ارائه داده شده است. بنابراین به مسیر زیر بروید : C:/Program Files (x86)/Microsoft Visual Studio 2017/Enterprise/VC/Redist/14.x.x/onecore/x64/Microsoft.VC150.CRT سپس فایلهای موجود در پوشه را کپی و در کنار برنامه قرار دهید در این صورت برنامه بدون هیچ خطایی اجرا خواهد شد. مگر اینکه به جز کتابخانه Qt و STL از کتابخانههای دیگری استفاده کرده باشید که در این صورت هم باید فایلهای مربوط به آنها را در کنار برنامه قرار دهید.
-
1 امتیازکتابخانهی اوپن سی اِل مخفف Open Computing Language بستری برای برنامههایی که قرار است بر سکوهای ناهمگن یا تکیه بر پردازندههای مرکزی و پردازندههای گرافیکی و سایر پردازندهها اجرا شوند. این کتابخانه دارای یک زبان بر پایهی C99 و C++11 برای نوشتن کرنلها و همچنین رابطهای برنامهنویسی برای تعریف و پس از کنترل بستر استفاده شوند را دارا است. این کتابخانه چندپردازندگی را با استفاده از روشهای وظیفه محور (Task-Based) و داده محور (Data-Based) پشتیبانی میکند. اوپن سی اِل توسط هر دو شرکت AMD/ATI و Nvidia پذیرفته شده است. در طراحی اوپن سی اِل، مقدار زیادی از رابطههای پردازشی با Cuda و رقیب آن، مایکروسافت دایرکت کامپیوت (Direct-Compute) به اشتراک گذاشته شده است. پیاده سازیهای مربوطه از طرف Altea, AMD, Apple صورت گرفته شده است که در این میان OpenCL همراه با OpenGL به نفع Metal2 منسوخ شده اند. همچنین IBM, Imagination, Intel, Nvidia, Qualcomm, Samsung, Vivante, Xilinx و Ziilabs آن را پذیرفتهاند. این کتابخانه یکی از قدرتمند ترین پلتفرمهای موجود در بازار در مقابل DirectX میباشد گه از سوی کمیتهی Khronos Group اعلام شده است که پا به پای DirectX ه فعالیتش ادامه میدهد. جالب است بدانید نسخههای جدید این کتابخانه با قدرت بسیار زیادی بر روی PS4 و PS4 Pro استفاده میشوند. از آنجایی که PS4 از معماری GCN استفاده میکند، قابلیت پشتیبانی از DiectX 12 نیز برای آن فراهم شده است. بهتر است بدانید توسعه اصلی این پلتفرم توسط اپل انجام شده است که در حال حاضر توسط کمیتهی Khronos Group اداره میشود که بر روی طیف وسیعی از سخت افزارهای روز و کارت گرافیکیهای محتلف گرفته تا پردازندههای موجود پشتیبانی میشود. قدرت روز افزون اوپن سی اِل در حال افزایش است و شاید اگر قدرت و سرمایهی مایکروسافت نبود، OpenCL سلطان بی چون و چرای بازار میشد. کودا با وجود انکار انویدیا، فریم ورکی است اختصاصی که در بسیاری از محصولات مورد استفاده قرار میگیرد. انویدیا تلاش میکند رقبایش را به استفاده از کودا وادار کند، اما تلاشش نتیجه بخش نبوده و میبینم که از این فریم ورک بیشتر در توسعه محصولات خودش استفاده میشود. از طرفی میتوان ادعا کرد که Direct Compute هم اختصای است. چون فقط بر روی ویندوز و دایرکت اِکس ۱۱ به بالا اجرا میشود. اما OpenCL منبع باز است و بسیاری از شرکتهای بزرک از جمله Nvidia از آن پشتیبانی میکنند. جهت نصب و راه اندازی این کتابخانه برای پردازندههای Intel به این بخش مراجعه کرده و نسخهی Amd را در این بخش و برای Nvidia از این صفحه دریافت و استخراج نمایید. این کتابخانه در قالب SDK شامل include و lib تحت تو معماری x86 و x64 میباشد که باید در محیط توسعهی نرمافزاری خود آن را معرفی کنید. در محیط Qt Creator طبق آموزشهای قبل اقدام کنید. با توجه به اینکه ما SDK مربوطه را در مسیر C:/IntelOpenCL/sdk استخراج کردهایم، کُد فایل .pro به صورت زیر خواهد بود: LIBS += -L$$PWD/../../../../../Intel/OpenCL/sdk/lib/x86/ -lOpenCL INCLUDEPATH += $$PWD/../../../../../Intel/OpenCL/sdk/include DEPENDPATH += $$PWD/../../../../../Intel/OpenCL/sdk/include جهت آزمایش عملکرد کتابخانه توجه داشته باشید که فایلهای هدر در پلتفرم macOS در پوشهی OpenCL و در محیطهای ویندوز و لینوکس در مسیر CL موجود میباشند. #ifdef __APPLE__ #include <OpenCL/opencl.h> #else #include <CL/cl.hpp> #endif در ادامه کد زیر نتیجهی جمع دو آرایه با یکدیگر را تحت OpenCL اجرا خواهد گرد: #include <iostream> #include <vector> #ifdef __APPLE__ #include <OpenCL/opencl.h> #else #include <CL/cl.hpp> #include <CL/opencl.h> #endif using namespace std; int main(){ //get all platforms (drivers) std::vector<cl::Platform> all_platforms; cl::Platform::get(&all_platforms); if(all_platforms.size()==0){ std::cout<<" No platforms found. Check OpenCL installation!\n"; exit(1); } cl::Platform default_platform=all_platforms[0]; std::cout << "Using platform: "<<default_platform.getInfo<CL_PLATFORM_NAME>()<<"\n"; //get default device of the default platform std::vector<cl::Device> all_devices; default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices); if(all_devices.size()==0){ std::cout<<" No devices found. Check OpenCL installation!\n"; exit(1); } cl::Device default_device=all_devices[0]; std::cout<< "Using device: "<<default_device.getInfo<CL_DEVICE_NAME>()<<"\n"; cl::Context context({default_device}); cl::Program::Sources sources; // kernel calculates for each element C=A+B std::string kernel_code= " void kernel simple_add(global const int* A, global const int* B, global int* C){ " " C[get_global_id(0)]=A[get_global_id(0)]+B[get_global_id(0)]; " " } "; sources.push_back({kernel_code.c_str(),kernel_code.length()}); cl::Program program(context,sources); if(program.build({default_device})!=CL_SUCCESS){ std::cout<<" Error building: "<<program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(default_device)<<"\n"; exit(1); } // create buffers on the device cl::Buffer buffer_A(context,CL_MEM_READ_WRITE,sizeof(int)*10); cl::Buffer buffer_B(context,CL_MEM_READ_WRITE,sizeof(int)*10); cl::Buffer buffer_C(context,CL_MEM_READ_WRITE,sizeof(int)*10); int A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int B[] = {0, 1, 2, 0, 1, 2, 0, 1, 2, 0}; //create queue to which we will push commands for the device. cl::CommandQueue queue(context,default_device); //write arrays A and B to the device queue.enqueueWriteBuffer(buffer_A,CL_TRUE,0,sizeof(int)*10,A); queue.enqueueWriteBuffer(buffer_B,CL_TRUE,0,sizeof(int)*10,B); //run the kernel //alternative way to run the kernel cl::Kernel kernel_add=cl::Kernel(program,"simple_add"); kernel_add.setArg(0,buffer_A); kernel_add.setArg(1,buffer_B); kernel_add.setArg(2,buffer_C); queue.enqueueNDRangeKernel(kernel_add,cl::NullRange,cl::NDRange(10),cl::NullRange); queue.finish(); int C[10]; //read result C from the device to array C queue.enqueueReadBuffer(buffer_C,CL_TRUE,0,sizeof(int)*10,C); std::cout<<" result: \n"; for(int i=0;i<10;i++){ std::cout<<C[i]<<" "; } return 0; } نتیجه خروجی جمع دو آرایه با یکدیگر و همچنین شناسایی پلتفرمهای قابل پشتیبانی در OpenCL: Using platform: Intel(R) OpenCL Using device: Intel(R) HD Graphics 4400 result: 02435768109
-
1 امتیازجزئیات در ++C ویرایش ۱۷: کد نویسی ساده با توجه به مشخصاتی که در استاندارد ISO/IEC 14882:2017 که ارائه شده است، ویژگیهای جدید برای این معرفی میشوند تا کد شما تمیز تر و بهتر و در کل رَساتر اعمال شوند. این مقاله را برای مطلع شدن از جزئیات بیشتر بخوانید. سیپلاسپلاس ۱۷ چندین ویژگی بزرگ زبان را ارائه میدهد که باعث میشود کد ما زیباتر و بهتر شود. بنابراین بیایید باهم یک نگاهی به این ویژگیها داشته باشیم. ممکن است شما بگویید که بیشترین ویژگیهای جدید زبان (به جز پیشرفت های کتابخانه استاندارد - STL) برای نوشتن کد ساده تر و پاکتر میباشند. با توجه به مجموعه جزئیات سیپلاسپلاس ۱۷ که بسیاری از چیزهای بزرگ را مورد بررسی قرار داده است، ما امروز تنها برای بعضی از ویژگی ها که از داخل این مجموعه عظیم بیرون کشیدهایم اشاره خواهیم داشت که باعث میشود کد شما فشردهتر و بهینه تر شود. پیوندهای ساخت یافته / اعلانهای تجزیه عبارت Init-statement برای if/switch متغیرهای درون خطی (inline) شرط constexpr if و چند موارد دیگر پیوندهای ساخت یافته، آیا اغلب با tuple ها کار کردهاید؟ اگر نه، پس احتمالاً باید به آن نگاهی کنید. tuple ها تنها برای بازگشت مقادیر چند گانه از یک تابع پیشنهاد نمیشوند، آنها پشتیبانی ویژگیای از زبان را داشتند. به طوری که باعث میشود کد ساده تر و پاکتر شود. برای مثال (std::tie که از مرجع اصلی سیپلاسپلاس به دست آمده است) به صورت زیر است: std::set<S> mySet; S value{42, "Test", 3.14}; std::set<S>::iterator iter; bool inserted; // unpacks the return val of insert into iter and inserted std::tie(iter, inserted) = mySet.insert(value); if (inserted) std::cout << "Value was inserted\n"; توجه داشته باشید که باید iter و inserted را ابتدا وارد کرده باشید. سپس شما میتوانید از std::tie استفاده کنید. با این حال این بخش کوچکی از کد نمونه است: std::set<S> mySet; S value{42, "Test", 3.14}; auto [iter, inserted] = mySet.insert(value); اینجا توجه داشته باشید که یک خط به جای سه خط جایگزین شده است! این کد سادهتر و خواناتر و درعین حال ایمن تر است، اینطور نیست؟ همچنین، شما هم اکنون میتوانید از const استفاده کنید و آن را به صورت const auto [iter inserted] بنویسید که صحیح است. پیوند ساختاری تنها به tuple ها ختم نمیشود، چرا که ما سه مورد دیگر را داریم: اگر مقدار دهی اولیه یک آرایه باشد: // works with arrays: double myArray[3] = { 1.0, 2.0, 3.0 }; auto [a, b, c] = myArray; اگر مقدار دهی اولیه std::tuple_size<> را پشتیبانی کند و تابع get را فراهم کند که شایع ترین مورد است. auto [a, b] = myPair; // binds myPair.first/second به عبارت دیگر، شما میتوانید کلاسهای خود را پشتیبانی کنید، با فرض این که شما تابع get را در پیاده سازی رابط کلاس خود اضافه کرده باشید. اگر مقدار دهی اولیه فقط شامل اعضای عمومی شود در این صورت: struct S { int x1 : 2; volatile double y1; }; S f(); const auto [ x, y ] = f(); در حال حاضر این روش برای دریافت یک مرجع از یک عضو tuple آسان است. auto& [ refA, refB, refC, refD ] = myTuple; و یکی از جالبترین استفادهها (پشتیبانی از حلقهها است): std::map myMap; for (const auto & [k,v] : myMap) { // k - key // v - value } پیوند ساختاری یا تقسیم بندی اعلانها برای این ویژگی، ممکن است شما نام های دیگری را دیده باشید، "اعلان تجزیه". همانطور که میبینیم، این دو نام در نظر گرفته شده است، اما فعلاً استاندارد سازی در حالت پیشنویسه است و با نام "پیوندهای ساختاری" میباشند. جزئیات بیشتر در رابطه با این مورد در اسناد P0217R3، P0144R0 و P0615R0 موجود هستند. همچنین این مورد با کامپایلرهای GCC 7.0،MSVC2017 و Clang 4.0 سازگار است. عبارت Init-statement برای if/switch نسخه جدید عبارت شرطی if و switch در سیپلاسپلاس جدید به صورت زیر است: if (init; condition) , switch (init; condition) قبلاً باید به صورت زیر مینوشتیم: { auto val = GetValue(); if (condition(val)) // on success else // on false... } در اینجا val یک دامنه جدا کننده بدون دارد که باعث "نشت - فقدان" در خاتمه دهنده دامنه خواهد شد. در حالی که شما در نسخه جدید میتوانید به صورت زیر بنویسید: if (auto val = GetValue(); condition(val)) // on success else // on false... متغیر val تنها در داخل عبارات if و else قابل رویت است، بنابراین آن یک "نَشت" نخواهد داشت. condition ممکن است چندین عبارت باشد نه تنها if بنابراین متغیر val یکی از دو مقدار true/false را خواهد داشت. چرا این ویژگی کاربرد دارد؟ اجازه دهید تا به شما بگوییم زمانی که میخواهید چندین چیز را در یک رشته را جستجو کنید به صورت زیر خواهید داشت: const std::string myString = "My Hello World Wow"; const auto it = myString.find("Hello"); if (it != std::string::npos) std::cout << it << " Hello\n" const auto it2 = myString.find("World"); if (it2 != std::string::npos) std::cout << it2 << " World\n" ما باید از نامهای مختلفی برای it استفاده کنیم و یا اینکه آن را با دامنه خاتمه دهنده جدا سازیم. { const auto it = myString.find("Hello"); if (it != std::string::npos) std::cout << it << " Hello\n" } { const auto it = myString.find("World"); if (it != std::string::npos) std::cout << it << " World\n" } عبارت جدید شرطی if در نسخه جدید یک دامنه اضافه را در یک خط ایجاد میکند. if (const auto it = myString.find("Hello"); it != std::string::npos) std::cout << it << " Hello\n"; if (const auto it = myString.find("World"); it != std::string::npos) std::cout << it << " World\n"; همانطور که قبلاً اشاره شده است، متغیر تعریف شده در عبارت شرطی if در بلوک دیگری قابل مشاهده است. بنابراین شما میتواین به صورت زیر بنویسید: if (const auto it = myString.find("World"); it != std::string::npos) std::cout << it << " World\n"; else std::cout << it << " not found!!\n"; به علاوه، شما میتوانید آن را با پیوند ساختاری بر اساس کد نمونه از جانب (Herb Sutter) استفاده کنید: // better together: structured bindings + if initializer if (auto [iter, succeeded] = mymap.insert(value); succeeded) { use(iter); // ok // ... } // iter and succeeded are destroyed here جزئیات بیشتر در اسناد زیر آمده است: سند P0305R1 ویدیو موجود در یوتیوب با عنوان (C++ Weekly - Ep 21 C++17’s if and switch Init Statements) این مورد با کامپایلرهای GCC 7.0،MSVC-2017.3 و Clang 3.9 سازگار است. متغیرهای درون خطی (inline) با شروع مقدار دهی دادههای غیر استاتیک، اکنون میتوانیم یک متغیر عضو را دی یک مکان اعلام کنیم. با این حال، با متغیرهای استاتیک یا const static، معمولاً باید آن را در برخی از فایلهای cpp تعریف کنید. در سیپلاسپلاس ۱۱ و کلید واژه constexpr که مارا قادر میسازد تا در یک مکان اعلان و تعریف متغیرهای استاتیک را انجام دهیم، اما این امکان تنها به constexpr محدود میشود. قبلاً فقط روشها/توابع میتوانستند به عنوان inline تعریف شوند، حالا شما میتوانید این کار را با متغیر ها در داخل فایل هدر انجام دهید. یک متغیر اعلام شده درون خطی معنای مشاهبی دارد بنابراین همانند یک تابع inline تعریف میشود. آن را میتوان به واحدهای ترجمه چند گانه نیز تعریف کرد. مثالهای زیر را ببینید: struct MyClass { static const int sValue; }; inline int const MyClass::sValue = 777; و حتی struct MyClass { inline static const int sValue = 777; }; همچنین توجه داشته باشید که متغیرهای constexpr به طور ضمنی inline هستند، بنابراین نیازی به استفاده به صورت constepr inline myVar = 10; نمیباشد. این ویژگی چرا کد را ساده تر میکند؟ برای مثال، تعداد زیادی از هدرها در کتابخانه تنها تعدادی از روش های (هک) را محدود میکنند (مانند استفاده توابع درون خطیinline و یا قالب ها) و در نهایت مزیت constexpr این است که مقدار دهی اولیه شما نباید constexpr باشد. جزئیات بیشتر در رابطه با این ویژگی در سند زیر موجود است: سند P0386R2 این مورد با کامپایلرهای GCC 7.0 و Clang 3.9 سازگار است اما فعلاً با MSVC سازگاری ندارد. ویژگی مربوط به constexpr if ممکن است در بعضی جاها به قابلیت std::enable_if در سیپلاسپلاس ۱۴ نگاه کنید که آن به راحتی با constexpr if جایگزین میشود. بنابراین، در اکثر موارد، ما اکنون میتوانیم تنها با نوشتن عبارت یک constexpr if این کار را بهتر و تمیز تر انجام دهیم. این ویژگی برای برنامه نویسی metaprogramming/template بسیار مهم است که احتمالاً طبیعت آن بسیار پیچیده خواهد بود. یک مثال ساده با تابع Fibonacci: template<int N> constexpr int fibonacci() { return fibonacci<N-1>() + fibonacci<N-2>(); } template<> constexpr int fibonacci<1>() { return 1; } template<> constexpr int fibonacci<0>() { return 0; } حال میتوان آن را تقریباً در یک حالت نرمال (نسخه بدون کامپایل) نوشت: template<int N> constexpr int fibonacci() { if constexpr (N>=2) return fibonacci<N-1>() + fibonacci<N-2>(); else return N; } در رویداد ۱۸ هم جلسات هفتگی سیپلاسپلاس در جیسون ترنر نمونهای را میتوان یافت که در آن عبارت constexpr if هیچ منطق اتصال کوتاهی را در زمان کامپایل انجام نمیدهد، بنابراین این کد باید کامپایل شود: if constexpr (std::is_integral<T>::value && std::numeric_limits<T>::min() < 10) { } در کد فوق برای T شما در std::string خطایی کامپایل را دریافت خواهید کرد زیرا numeric_limits برای رشته ها تعریف نشده اند. در جلسات C++NOW 2017 آقای Bryce Leblbach با عنوان جلسه خود C++17 Features در ۱۶ دقیقه مثال بسیار زیبایی را در رابطه باconstexpr if زد که میتواند برای تابع get استفاده شود که آن برای پیوند ساختاری مورد استفاده قرار میگیرد. struct S { int n; std::string s; float d; }; template <std::size_t I> auto& get(S& s) { if constexpr (I == 0) return s.n; else if constexpr (I == 1) return s.s; else if constexpr (I == 2) return s.d; } قبلاً ما باید به صورت زیر مینوشتیم: template <> auto& get<0>(S &s) { return s.n; } template <> auto& get<1>(S &s) { return s.s; } template <> auto& get<2>(S &s) { return s.d; } همانطور که میبینید، مشکل سوال برانگیز اینجاست که کد در این جا ساده تر است. اگر چه در این مورد فقط از یک ساختار ساده استفاده شده است، با برخی از نمونه های واقعی دنیا، کد نهایی باید بسیار پیچیده تر از این باشد بنابراین باید constexpr if کد تمیز تری نسبت به این مورد باشد. این مورد با کامپایلرهای GCC 7.0،MSVC-2017.3 و Clang 3.9 سازگار است. ویژگیهای دیگر ما میتوانیم در رابطه با بسیاری از ویژگی های جدید سیپلاسپلاس صحبت کنیم اما در این پست ما بیشتر در رابطه با قطعات بزرگتر تمرکز کردهایم. با این حال، فقط برای یادآوری، ممکن است بخواهید ویژگیهای زیر را در نظر بگیرید که آنها نیز کد ها را ساده تر میکنند: الگو یا قالبها (templates) عبارت Fold الگو برای کلاس ها بنابراین برای ذکر ویژگیهای بیشتر در رابطه با نسخه جدید در پستهای آن ها را پوشش خواهیم داد. شک نکنید که، سیپلاسپلاس ۱۷ پیشرفت واقعی را در برابر کد های جمع و جور و آسان فراهم گرده است. یکی از بهترین چیزها constexpr است که آن به ما اجازه میدهد کد template/metaprogramming را به روش کد استاندارد شده بنویسیم. این یک مزیت بسیار بزرگی است. ویژگی دوم: پیوند ساخت یافته (که حتی برای حلقه ها کار میکند) مانند حسی را القا میکند که در زبانهای پویایی مثل Python وجود دارد. همانطور که میبینید، تمام ویژگیهای ذکر شده در حال حاضر در Clang، MSVC و GCC قابل اجرا هستند. اگر شما با نسخههای اخیر این کامپایلر ها کار میکنید میتواین بلافاصله با سی++ ۱۷ کار کرده و آن را تجربه کنید.