مقدمه
زبان برنامهنویسی C++ از زمان استانداردسازی اولیه خود در سال ۱۹۹۸ (معروف به C++98) به طور مداوم در حال تکامل بوده است. هدف از این تکامل، بهبود کارایی، افزایش امنیت، تسهیل توسعه نرمافزارهای پیچیده و همگام شدن با نیازهای روزافزون صنعت نرمافزار بوده است. در طول این سالها، استانداردهای متعددی به C++ اضافه شدهاند که هر کدام مجموعهای از ویژگیهای جدید و بهبودهای مهم را به این زبان آوردهاند. این مقاله به بررسی اجمالی این ویژگیهای کلیدی اضافه شده به C++ از زمان استاندارد ۱۹۹۸ به بعد میپردازد.
C++03: اصلاحات و بهبودهای اولیه
استاندارد C++03 که در سال ۲۰۰۳ منتشر شد، در مقایسه با C++98، یک بازنگری جزئی محسوب میشود. هدف اصلی C++03، رفع ابهامات و مشکلات موجود در استاندارد C++98 و بهبود سازگاری بین پیادهسازیهای مختلف کامپایلرها بود. اگرچه C++03 ویژگیهای زبانی جدیدی را به طور عمده معرفی نکرد، اما اصلاحات و بهبودهای مهمی را در کتابخانه استاندارد و مشخصات زبانی اعمال کرد.
از جمله مهمترین تغییرات C++03 میتوان به موارد زیر اشاره کرد:
- اصلاح تخصصسازی
std::vector<bool>: رفتار غیراستاندارد و مشکلساز تخصصسازیstd::vector<bool>درC++98اصلاح شد تا سازگاری و عملکرد آن بهبود یابد. - بهبود مدیریت جریان ورودی/خروجی: اصلاحات و بهبودهایی در کتابخانه جریان ورودی/خروجی (
iostream) اعمال شد تا عملکرد و امنیت آن افزایش یابد. - رفع ابهامات و تناقضات: بسیاری از ابهامات و تناقضات موجود در استاندارد
C++98که منجر به تفسیرهای مختلف توسط کامپایلرهای متفاوت میشد، درC++03رفع شدند.
به طور خلاصه، C++03 یک گام مهم در جهت پایداری و سازگاری C++ بود، هرچند تغییرات آن در مقایسه با استانداردهای بعدی، نسبتاً محدود به شمار میروند.
C++11: انقلاب در C++
استاندارد C++11 که در سال ۲۰۱۱ منتشر شد (و در ابتدا به عنوان C++0x شناخته میشد)، یک تحول بزرگ در تاریخ C++ به شمار میرود. C++11 مجموعهای گسترده از ویژگیهای جدید را به زبان و کتابخانه استاندارد اضافه کرد که به طور چشمگیری قدرت، انعطافپذیری و کارایی C++ را افزایش داد. C++11 به طور اساسی نحوه برنامهنویسی به C++ را تغییر داد و بسیاری از الگوهای برنامهنویسی مدرن را در این زبان امکانپذیر ساخت.
برخی از مهمترین ویژگیهای معرفی شده در C++11 عبارتند از:
- عبارات لامبدا (
Lambda Expressions): عبارات لامبدا امکان تعریف توابع بینام (anonymous functions) را به صورت درونخطی در کد فراهم میکنند. این ویژگی به سادهسازی کد و افزایش خوانایی آن به خصوص در استفاده از الگوریتمهای کتابخانه استاندارد کمک شایانی میکند. عبارات لامبدا در واقع توابع کوچکی هستند که میتوانند به عنوان آرگومان به توابع دیگر ارسال شوند یا در محل تعریف استفاده شوند. - مراجع مقدار-راست (
Rvalue References) و معناشناسی انتقال (Move Semantics): این ویژگیها مشکل کپیسازی غیرضروری دادهها را درC++حل میکنند. معناشناسی انتقال امکان “انتقال” منابع از یک شی موقت (مقدار-راست) به یک شی دیگر را فراهم میکند، به جای اینکه دادهها را به طور کامل کپی کند. این امر به ویژه در مواردی که با اشیای بزرگ و پیچیده سر و کار داریم، به بهبود چشمگیر کارایی منجر میشود. - کلمه کلیدی
auto: کلمه کلیدیautoامکان استنتاج نوع متغیر را توسط کامپایلر فراهم میکند. به این معنی که در بسیاری از موارد، نیازی به مشخص کردن صریح نوع متغیر نیست و کامپایلر میتواند نوع آن را بر اساس مقدار تخصیص داده شده استنتاج کند. این ویژگی کد را کوتاهتر و خواناتر میکند و از خطاهای نوعدهی دستی جلوگیری میکند. - حلقه
forمبتنی بر رنج (Range-based for loop): حلقهforمبتنی بر رنج روشی ساده و خوانا برای پیمایش عناصر یک مجموعه (مانند آرایه، بردار، لیست و غیره) فراهم میکند. این نوع حلقه نیاز به استفاده از اندیس یا تکرارکننده (iterator) را از بین میبرد و کد را مختصرتر و کمخطاتر میسازد. - قالبهای واریادیک (
Variadic Templates): قالبهای واریادیک امکان تعریف قالبهایی را فراهم میکنند که میتوانند تعداد متغیری از آرگومانهای قالب را بپذیرند. این ویژگی بسیار قدرتمند است و امکان ساخت کتابخانهها و الگوهای کلیتر و انعطافپذیرتر را فراهم میکند. nullptr: جایگزین ایمنتر برای ماکروNULLکه برای اشارهگرهای پوچ استفاده میشد.nullptrیک کلمه کلیدی نوع-ایمن است که از بسیاری از ابهامات و مشکلات مرتبط با استفاده ازNULLجلوگیری میکند.- پشتیبانی از همروندی (
Concurrency Support) با کتابخانهstd::thread:C++11پشتیبانی از برنامهنویسی همروند را به صورت استاندارد در کتابخانه خود ارائه کرد. کتابخانه<thread>امکان ایجاد و مدیریت ریسهها (threads) را فراهم میکند و ابزارهایی برای همگامسازی ریسهها و جلوگیری از شرایط مسابقه (race conditions) ارائه میدهد. - اشارهگرهای هوشمند (
Smart Pointers) مانندstd::shared_ptrوstd::unique_ptr: اشارهگرهای هوشمند به طور خودکار مدیریت حافظه تخصیص یافته را انجام میدهند و از نشت حافظه (memory leaks) جلوگیری میکنند.std::shared_ptrامکان اشتراکگذاری مالکیت یک منبع را بین چندین اشارهگر فراهم میکند، در حالی کهstd::unique_ptrمالکیت انحصاری یک منبع را تضمین میکند. constexpr: این ویژگی امکان ارزیابی توابع و متغیرها در زمان کامپایل را فراهم میکند. توابع و متغیرهایconstexprمیتوانند در زمان کامپایل محاسبه شوند و نتیجه آنها به عنوان یک مقدار ثابت در کد گنجانده شود. این امر به بهبود کارایی و بهینهسازی کد کمک میکند.- لیستهای مقداردهی اولیه (
Initializer Lists): لیستهای مقداردهی اولیه یک نحو یکنواخت برای مقداردهی اولیه اشیا با استفاده از لیستهای داخل آکولاد{}فراهم میکنند. این نحو هم برای انواع دادههای داخلی و هم برای انواع دادههای تعریف شده توسط کاربر قابل استفاده است و کد را خواناتر و سازگارتر میکند.
C++11 استاندارد مهمی بود که C++ را به یک زبان مدرن و قدرتمند تبدیل کرد و زمینه را برای استانداردهای بعدی فراهم ساخت.
C++14: بهبودها و تکمیل ویژگیهای C++11
استاندارد C++14 که در سال ۲۰۱۴ منتشر شد، بیشتر بر تکمیل و بهبود ویژگیهای معرفی شده در C++11 تمرکز داشت. C++14 ویژگیهای جدید زبانی کمتری نسبت به C++11 معرفی کرد، اما بهبودهای مهمی را در برخی از ویژگیهای کلیدی C++11 اعمال کرد و ابزارهای مفید جدیدی را به کتابخانه استاندارد افزود.
برخی از مهمترین ویژگیهای C++14 عبارتند از:
- لامبداهای عمومی (
Generic Lambdas):C++14امکان استفاده ازautoبه عنوان نوع پارامتر در عبارات لامبدا را فراهم کرد. این ویژگی باعث میشود که لامبداها عمومیتر و انعطافپذیرتر شوند و بتوانند با انواع مختلفی از دادهها کار کنند. - استنتاج نوع بازگشتی برای توابع (
Return Type Deduction for Functions):C++14امکان استنتاج نوع بازگشتی توابع را در برخی موارد فراهم کرد. اگر بدنه تابع به طور کامل از عبارتreturnتشکیل شده باشد، کامپایلر میتواند نوع بازگشتی تابع را استنتاج کند، مشابه عملکرد کلمه کلیدیautoبرای متغیرها. - لیترالهای باینری و جداکنندههای رقم (
Binary Literals and Digit Separators):C++14امکان استفاده از لیترالهای باینری (با پیشوند0b) و جداکنندههای رقم (با استفاده از علامت') در اعداد را فراهم کرد. این ویژگیها به خوانایی بیشتر اعداد طولانی و باینری در کد کمک میکنند. std::make_unique:C++14تابع کمکیstd::make_uniqueرا برای ساخت اشیایstd::unique_ptrمعرفی کرد.std::make_uniqueروشی ایمنتر و کارآمدتر برای ایجادstd::unique_ptrنسبت به استفاده مستقیم از سازنده آن است.- بهبودهای
constexpr:C++14محدودیتهایconstexprرا کاهش داد و امکان استفاده از دستورات و الگوریتمهای پیچیدهتر را در توابعconstexprفراهم کرد.
C++14 یک استاندارد تکمیلی بود که C++11 را قویتر و کاربردیتر ساخت و راه را برای استانداردهای بعدی هموار کرد.
C++17: سادهسازی و افزایش قدرت بیان
استاندارد C++17 که در سال ۲۰۱۷ منتشر شد، بر سادهسازی زبان، افزایش قدرت بیان و بهبود کارایی تمرکز داشت. C++17 ویژگیهای زبانی و کتابخانهای متعددی را معرفی کرد که کدنویسی به C++ را لذتبخشتر و کارآمدتر ساخت.
برخی از ویژگیهای مهم C++17 عبارتند از:
- عبارات تاشو (
Fold Expressions): عبارات تاشو روشی ساده و مختصر برای انجام عملیات بر روی تمام عناصر یک بسته پارامتر قالب واریادیک (variadic template parameter pack) فراهم میکنند. این ویژگی به ویژه در برنامهنویسی متا (metaprogramming) بسیار کاربردی است. - پیوندهای ساختاریافته (
Structured Bindings): پیوندهای ساختاریافته امکان “باز کردن” (unpack) تاپلها (tuples)، جفتها (pairs) و ساختارها (structs) را به متغیرهای جداگانه فراهم میکنند. این ویژگی کد را خواناتر و کوتاهتر میکند، به خصوص هنگام کار با توابع چندمقدار بازگشتی. - متغیرهای خطی (
Inline Variables):C++17امکان تعریف متغیرهای خطی (inline variables) را در فایلهای سرآیند (header files) فراهم کرد. این ویژگی مشکل تعاریف چندگانه متغیرهایinlineرا که در استانداردهای قبلی وجود داشت، حل میکند و به سازماندهی بهتر کد و کاهش حجم کامپایل کمک میکند. if constexpr: عبارتif constexprامکان انجام شاخهبندی شرطی در زمان کامپایل را فراهم میکند. این ویژگی به نوشتن کد کلیتر و بهینهتر کمک میکند، چرا که بخشهای غیرضروری کد در زمان کامپایل حذف میشوند.- استنتاج آرگومان قالب برای قالبهای کلاس (
Template Argument Deduction for Class Templates - CTAD):CTADامکان استنتاج آرگومانهای قالب برای قالبهای کلاس را در بسیاری از موارد فراهم میکند. پیش ازC++17، هنگام ایجاد شی از یک قالب کلاس، همیشه باید آرگومانهای قالب را به صورت صریح مشخص میکردیم.CTADاین نیاز را در بسیاری از موارد برطرف میکند و کد را سادهتر و خواناتر میسازد. - انواع مجموعهای
std::optional،std::variant،std::any:C++17سه نوع مجموعهای جدید را به کتابخانه استاندارد اضافه کرد:std::optionalبرای نشان دادن مقدار اختیاری (ممکن است وجود داشته باشد یا نباشد)،std::variantبرای نگهداری مقداری از میان مجموعهای از انواع مختلف، وstd::anyبرای نگهداری مقداری از هر نوعی. این انواع به انعطافپذیری و قدرت بیانC++در کار با دادههای متنوع و نامشخص میافزایند. - الگوریتمهای موازی (
Parallel Algorithms):C++17نسخههای موازیشدهای از الگوریتمهای استاندارد کتابخانه<algorithm>را ارائه داد. این الگوریتمها میتوانند به طور خودکار از چند ریسه (multi-threading) برای بهبود کارایی در پردازش مجموعههای داده بزرگ استفاده کنند.
C++17 یک استاندارد مهم دیگر بود که C++ را به زبانی قدرتمندتر، کارآمدتر و آسانتر برای استفاده تبدیل کرد.
C++20: مدرنترین استاندارد C++ با تمرکز بر کارایی و امنیت
استاندارد C++20 که در سال ۲۰۲۰ منتشر شد، به عنوان مدرنترین و پیشرفتهترین استاندارد C++ شناخته میشود. C++20 ویژگیهای انقلابی و بنیادینی را به زبان و کتابخانه استاندارد اضافه کرد که تمرکز آنها بر بهبود کارایی، افزایش امنیت، سادهسازی برنامهنویسی و همگام شدن با حوزههای جدید مانند هوش مصنوعی و یادگیری ماشین است.
برخی از مهمترین ویژگیهای کلیدی C++20 عبارتند از:
- مفاهیم (
Concepts): مفاهیم یک سیستم قدرتمند برای تعریف محدودیتها (constraints) بر روی پارامترهای قالب واریادیک هستند. مفاهیم به کامپایلر کمک میکنند تا خطاهای مربوط به استفاده نادرست از قالبها را زودتر و با پیامهای خطای واضحتر شناسایی کند. مفاهیم به طور چشمگیری برنامهنویسی قالب را ایمنتر و قابلفهمتر میسازند. - ماژولها (
Modules): ماژولها یک سیستم جدید برای سازماندهی و کامپایل کدC++ارائه میدهند که جایگزین سیستم سنتی فایلهای سرآیند (header files) میشود. ماژولها مشکلات مقیاسپذیری سیستم سرآیند را حل میکنند، زمان کامپایل را به طور چشمگیری کاهش میدهند،encapsulation(کپسولهسازی) را بهبود میبخشند و از تداخل نامها جلوگیری میکنند. - کوروتینها (
Coroutines): کوروتینها نوع جدیدی از توابع هستند که امکان نوشتن کد ناهمگام (asynchronous code) را به صورت همزماننما (synchronous-looking) فراهم میکنند. کوروتینها برای برنامهنویسی رویدادمحور (event-driven programming)، شبکهسازی و سایر کاربردهای نیازمند به کارایی بالا در مدیریت عملیات ناهمگام بسیار مناسب هستند. - رنجها (
Ranges): کتابخانه رنجها (Ranges library) یک رویکرد کاملاً جدید برای کار با مجموعههای داده (ranges) ارائه میدهد. رنجها بر پایه ترکیب عملیاتهای مختلف بر روی دادهها با استفاده از خط لوله (pipeline) استوار هستند و امکان نوشتن کد بسیار خوانا، مختصر و کارآمد برای پردازش دادهها را فراهم میکنند. - عملگر مقایسه سه-طرفه (
<=>–spaceship operator): عملگر مقایسه سه-طرفه یک عملگر جدید است که به طور همزمان عملگرهای مقایسهای مختلف مانند==،!=،<،<=،>و>=را برای یک نوع تعریف میکند. این عملگر به سادهسازی فرآیند تعریف عملگرهای مقایسهای برای انواع دادههای تعریف شده توسط کاربر کمک میکند. - بهبودهای
constexpr:C++20محدودیتهایconstexprرا باز هم کاهش داد و امکان استفاده از بسیاری از ویژگیهای کتابخانه استاندارد مانندstd::vectorوstd::stringدر توابع و متغیرهایconstexprرا فراهم کرد. این امر به بهبود کارایی و انعطافپذیری برنامهنویسی در زمان کامپایل کمک میکند. - کتابخانه تقویم و منطقه زمانی (
Calendar and Time-zone library - <chrono> improvements):C++20بهبودهای مهمی را به کتابخانه<chrono>برای کار با تاریخ، زمان و مناطق زمانی اضافه کرد. این بهبودها امکانات بسیار گستردهتری را برای محاسبات تاریخ و زمان درC++فراهم میکنند.
C++20 یک استاندارد پیشرو و قدرتمند است که C++ را به زبانی آماده برای چالشهای برنامهنویسی مدرن و آینده تبدیل میکند.
نتیجهگیری
از زمان استاندارد C++98، زبان C++ به طور مداوم در حال تکامل و پیشرفت بوده است. استانداردهای C++03، C++11، C++14، C++17 و C++20 مجموعهای غنی از ویژگیهای جدید و بهبودهای اساسی را به این زبان اضافه کردهاند. این ویژگیها C++ را به زبانی مدرن، قدرتمند، کارآمد و امن برای توسعه انواع مختلف نرمافزارها تبدیل کردهاند. توسعهدهندگان C++ با بهرهگیری از این ویژگیها میتوانند کدهایی با کارایی بالاتر، خوانایی بیشتر، قابلیت نگهداری بهتر و سطح امنیت بالاتر تولید کنند. ادامه این روند تکاملی نشان میدهد که C++ همچنان به عنوان یکی از زبانهای برنامهنویسی پیشرو و مهم در صنعت نرمافزار باقی خواهد ماند و نقش کلیدی خود را در توسعه فناوریهای آینده ایفا خواهد کرد.
