C++ (بخوانید سیپلاسپلاس /ˌsiːˌplʌsˈplʌs/) یک زبان برنامهنویسی همهمنظوره، همگردان (کامپایلری) و در اصل سطح بالا، شیءگرا و چندرگه است که از برنامهنویسی رویهای، تجرید دادهها و برنامهنویسی شیءگرا پشتیبانی میکند. این زبان دارای قابلیتهای انواع دادهٔ ایستا، نوشتار آزاد و چندمدلی میباشد و معمولاً زبان ترجمهشده با پشتیبانی از برنامهنویسی ساختیافته، برنامهنویسی شیءگرا و برنامهنویسی جنریک است. از آنجا که در ++C اشیاء را میتوان ابتدا به ساکن از کلاسهایی ایجاد کرد که به هیچگونه سلسله مراتب ردهها و وراثت مقید نیستند، لذا ++C از برنامهسازی شیء بنیاد (object-based programming) نیز پشتیبانی میکند.[9] C++ به همراه جد خود C از پرطرفدارترین زبانهای برنامهنویسی هستند. C++ یک زبان سطح میانی در نظر گرفته میشود؛ این زبان دارای قابلیتهای زبانهای برنامهنویسی سطح بالا و زبانهای برنامهنویسی سطح پایین بهصورت همزمان است.
پارادایمهای برنامهنویسی | چندالگویی: رویهای، تابعی، شیءگرا، همگانی |
---|---|
خانواده | سی |
طراحی شده توسط | بییارنه استراستروپ |
توسعهدهنده | ISO/IEC JTC1 (هیئت فنی مشترک ۱) SC22 (زیرکمیته ۲۲) WG21 (کارگروه ۲۱) |
ظهوریافته در | ۱۹۸۵ |
انتشار پایدار | C++20 (ISO/IEC 14882:2020)
/ ۱۵ دسامبر ۲۰۲۰ |
انتشار آزمایشی | C++23
/ ۱۷ مارس ۲۰۲۲ |
ایستا، نامی، نیمه استنتاجی | |
سیستمعامل | اکثر سیستمعاملهای اصلی |
.C, .cc, .cpp, .cxx, .c++, .h, .hh, .hpp, .hxx, .h++ | |
وبگاه | |
پیادهسازیهای بزرگ | |
جیسیسی، کلنگ، ویژوال سی++، سی++بیلدر، Intel C++ Compiler, IBM XL C++، EDG | |
متأثر از | |
ایدا،[1] الگول۶۸، سی، سیالیو،[1] امال، Mesa,[1] Modula-2،[1] سیمولا، اسمالتاک[1] | |
تأثیر گذاشته بر | |
ایدا، سی شارپ,[2] C99، Chapel,[3] کلوژر،[4] دی، جاوا,[5] JS++,[6] لوآ، Nim,[7] پرل, پیاچپی, پایتون،[8] راست، Seed7 | |
C++ توسط بییارنه استراستروپ ریاضیدان دانمارکی در سال ۱۹۷۹ در آزمایشگاههای بل (Bell Labs)، برای بهبود زبان سی و بر مبنای آن ساخته شد و آن را «C با کلاس» (C With Classes) نامگذاری نمود. در سال ۱۹۸۳ به C++ تغییر نام داد. توسعه با اضافه نمودن کلاسها و ویژگیهای دیگری مانند توابع مجازی، سربارگزاری عملگرها، وراثت چندگانه، قالب توابع و پردازش استثناء انجام شد. این زبان برنامهنویسی در سال ۱۹۹۸ تحت نام ISO/IEC ۱۴۸۸۲:۱۹۹۸ استاندارد شد. نسخهٔ فعلی استاندارد این زبان ISO/IEC ۱۴۸۸۲:۲۰۱۴ است.[10][11]
تاریخچهٔ زبان
استراستروپ کار بر روی زبان «C دارای کلاس» را در سال ۱۹۷۹ آغاز کرد. ایدهٔ ساخت این زبان جدید در زمان کار بر روی تز دکترای خود به ذهن استراستروپ خطور نمود. او متوجه شد که سیمولا دارای ویژگیهایی مناسب برای ساخت برنامههای بسیار بزرگ است اما برای استفادهٔ عملی بسیار کند است اما بیسیپیال با وجود سرعت بسیار زیاد برای ساخت برنامههای بزرگ، بسیار سطح پایین است. زمانی که استراستروپ کار خود را در آزمایشگاههای بل (Bell Labs) آغاز نمود با مشکل تحلیل هستهٔ یونیکس با توجه به محاسبات توزیع شده روبرو شده بود. با یادآوری تجربیات خود در دوران دکترا، او زبان C را با استفاده از ویژگیهای سیمولا گسترش داد. C به این دلیل انتخاب شد که یک زبان عمومی، سریع، قابل حمل، و در سطح گستردهای در حال استفاده بود. علاوه بر C و سیمولا، زبانهای دیگری مانند ALGOL ۶۸ ،ADA ,CLU و ML نیز بر ساختار این زبان جدید اثر گذاشتند. در ابتدا ویژگیهای کلاس، کلاسهای مشتق شده، کنترل نوع قوی، توابع درونخطی و آرگومانهای پیشفرض از طریق Cfront به C اضافه شد. اولین نسخهٔ تجاری در سال ۱۹۸۵ ارائه شد.
در سال ۱۹۸۳ نام زبان از «C با کلاس» به C++ تغییر یافت. ویژگیهای دیگر شامل توابع مجازی، سربارگزاری عملگر و نام تابع، ارجاعات، ثوابت، کنترل حافظه توسط کاربر بهصورت آزاد، کنترل نوع بهتر و توضیحات یکخطی به صورت BCPL با استفاده از «//» نیز به آن اضافه شد. در سال ۱۹۸۵ اولین نسخهٔ زبان برنامهنویسی C++ انتشار یافت و مرجع مهمی برای این زبان فراهم شد؛ در حالی که هیچ استاندارد رسمیای وجود نداشت. در سال ۱۹۸۹ ویرایش ۲٫۰ از زبان C++ ارائه شد. ویژگیهای جدیدی مانند ارثبری چندگانه، کلاسهای انتزاعی، اعضای ایستای توابع، اعضای ثابت تابع و اعضای حفاظت شده به آن اضافه شد. در سال ۱۹۹۰ «راهنمای مرجع C++» منتشر شد. این کار بنیان استانداردهای بعدی شد. آخرین ویژگیهای اضافه شده شامل موارد زیر بودند: قالب توابع، استثناها، فضاهای نام، تبدیلات جدید و یک نوع داده منطقی.
در حین تکامل ++C، کتابخانهٔ استاندارد سی++ نیز بهوجود آمد. اولین نسخهٔ کتاب استاندارد شامل کتابخانهٔ جریانات I/O بود که جایگزین printf و scanf شد. در ادامه مهمترین ویژگی اضافه شده Standard Template Library بودهاست.
استاندارد زبان
استانداردسازی ++C توسط یک گروه از تشکیلات ISO انجام میشود.[12] تاکنون ۶ نسخه از استاندارد این زبان منتشر شدهاست؛ و استاندارد ۲۳ نیز برای انتشار در سال ۲۰۲۳ برنامهریزی شدهاست.
در سال ۱۹۹۸ برای اولین بار پس از سالها کار کمیته مشترک ANSI–ISO این زبان تحت عنوان ISO/IEC 14882:1998 و نام غیررسمی C++98 استانداردسازی شد. بعدها در سال ۲۰۰۳ نسخه جدیدی از استاندارد یعنی ISO/IEC 14882:2003 انتشار یافت و برخی از مشکلات و باگهای C++98 در آن رفع شد.
در سال ۲۰۰۵ یک گزارش فنی به اسم «گزارش فنی کتابخانهٔ ۱» (که معمولاً به صورت اختصار TR۱ خوانده میشود) منتشر شد که مواردی جدید را برای اضافه کردن به کتابخانه استاندارد سی++ دربرداشت با این که این گزارش قسمتی از استاندارد نبود ولی بعدها در نسخه بعدی استاندارد یعنی C++11 اضافه شد.
نسخه بعدی با نام غیررسمی C++11 و استاندارد ISO/IEC 14882:2011 در تاریخ ۱۲ اوت ۲۰۱۱ مورد تأیید سازمان بینالمللی استانداردسازی قرار گرفت و جایگزین C++03 شد.
در سال ۲۰۱۴ نسخه ای دیگر از این زبان در تاریخ ۱۸ اوت ۲۰۱۴ با نام غیررسمی C++14 و استاندارد ISO/IEC 14882:2014 منتشر شد. هدف اصلی C++14 همانند C++03 رفع مشکلات و همچنین اضافه کردن ویژگیها و بهبود جزئی C++11 بودهاست.
انتشار نسخه بعدی استاندارد این زبان با نام C++1z در سال ۲۰۱۷ بود که توسط کمیته ++ISO C در اواسط ماه ژوئیه تولید شد و در ماه دسامبر تأیید و منتشر شد.
نسخه فعلی نیز با نام C++20 در دسامبر ۲۰۲۰ توسط کمیته استاندارد بهصورت رسمی منتشر شد.
انتظار میرود نسخه استاندارد بعدی نیز در سال ۲۰۲۳ بهطور رسمی منتشر شود.
در حالی که C++ به هیچ مؤسسهای وابسته نیست این مستندات بهصورت آزادانه در دسترس نیستند. گرچه نسخههای نهایی نشده (draft) این اسناد در دسترس همگان قرار میگیرد.
نام C++
این نام منسوب به ریک ماسکیتی (اواسط 1978) است و برای اولین بار در دسامبر سال ۱۹۸0 به کار برده شد. در طول مدت تحقیق این زبان بنام «C جدید» و بعدها «C با کلاس» خوانده شد. در علوم کامپیوتر هنوز هم C++ به عنوان ابرساختار C شناخته میشود. آخرین نام از عملگر ++ در زبان C (که برای افزایش مقدار متغیر به اندازهٔ یک واحد بکار میرود) و یک عرف معمول برای نشان دادن افزایش قابلیتها توسط + ناشی گشتهاست. با توجه به نقل قولی از استراستروپ: «این نام ویژگیها تکاملی زبان در C را نشان میدهد.» +C نام زبانی غیرمرتبط به این زبان است.
استراستروپ مبدأ این نام را در فصل اول کتاب خود «زبان برنامهنویسی C++» اشاره مینماید که معنی دیگر C++ را میتوان در ضمائم کتاب جرج ارول بنام ۱۹۸۴ یافت. در سه قسمت از زبان تخیلی Newspeak «کلمات C» برای اشاره به لغات فنی و حرفهای بکار میرود. «دو علامت +» برای ایجاد صفات عالی از صفات Newspeak به کار میرفت بنابراین C++ به معنای زبانی با بیشترین شباهت به C است.
وقتی که بهصورت خصوصی از ریک ماسکیتی در مورد این اسم سؤال شد او در جواب گفت که این اسم به صورت خودمانی در بین آنها به کار میرفتهاست و تصور نمیکردند که این نام به صورت نام رسمی این زبان درآید.
فلسفه
در کتاب «طراحی و تکامل C++» استراستروپ قوانین مورد استفاده در طراحی C++ را بیان مینماید. دانستن این قوانین به فهمیدن نحوه عملکرد C++ و چرایی آن کمک میکند. جزئیات بیشتر در کتاب قابل دسترسی است:
- C++ طراحی شدهاست تا یک زبان عمومی با کنترل نوع ایستا و همانند C قابل حمل و پربازده باشد.
- C++ طراحی شدهاست تا مستقیماً و به صورت جامع از چندین شیوه برنامهنویسی بتوان از آن استفاده کرد (برنامهنویسی ساختیافته، برنامهنویسی شیگرا، انتزاع داده، و برنامهنویسی جنریک).
- C++ طراحی شدهاست تا به برنامهنویس امکان انتخاب دهد حتی اگر این انتخاب اشتباه باشد.
- C++ طراحی شدهاست تا حداکثر تطابق با C وجود داشته باشد و یک انتقال راحت از C را ممکن سازد.
- C++ از بکاربردن ویژگیهای خاص که مانع از عمومی شدن است خودداری مینماید.
- C++ از ویژگیهایی که بکار برده نمیشوند استفاده نمیکند.
- C++ طراحی شدهاست تا بدون یک محیط پیچیده عمل نماید.
تفاوتها با زبان برنامهنویسی C
- سی پلاس پلاس بر خلاف سی، شیءگرا است؛ کلیدواژههای جدیدی مانند class ,template ,typename ,alignas ,alignof و بسیاری دارد که سی فاقد آن است.
- در سی پلاس پلاس به چندین نوع میتوان یک متغیر را مقداردهی اولیه کرد اما در سی تنها به روش کپی یا با عملگر =.
- معمولاً سرآیندهای سی پلاس پلاس بدون پسوند h. نوشته میشوند (با h. هم میشود) و کتابخانهٔ استاندارد سی هم میتواند با حرف c اول سرآیند داخل برنامه سی پلاس پلاس شامل شود؛ مانند:
#include <iostream>
#include <cstdio>
- در اینجا میتوان بهجای
stdio.h
،cstdio
را نوشت، اما بهجایiostream.h
،iostream
را نمیتوان نوشت.
- در اینجا میتوان بهجای
- در سی نمیتوان با عملگر == دو رشته حرف یا استرینگ را مقایسه نمود اما در سی پلاس پلاس میشود؛ برای مثال:
C:
#include <stdio.h>
int main(){
if("Salam" == "Salam"){
printf("Salam");
}
}
این برنامه هیچ خروجیای ندارد اما به جایش میتوان از تابع strcmp()
استفاده نمود.
++C:
#include <iostream>
int main(){
if("Salam" == "Salam"){
std::cout << "Salam" << std::endl;
}
}
خروجی این برنامه Salam میباشد.
- در زبان سی برای تعریف چندین متغیر نشانگر به صورت زنجیرهای نیاز به گذاشتن علامت ستاره '*' قبل هر متغیر بود اما اکنون به نوع بستگی دارد:
C:
const char *a,*b,*c;
++C:
const char* a,b,c;
- structها در سی پلاس پلاس میتوانند به عنوان یک کلاس نیز عمل کنند اما با این تفاوت که سطح دسترسی پیش فرض استراکتها
public
هستند. همچنین دیگر نیازی به گذاشتن کلیدواژهstruct
قبل تعریف متغیری با آن استراکت نیست:
C:
struct test{
int i,j;
};
int main(){
struct test t;
t.i = 2;
t.j = 3;
}
++C:
struct test{
private:
int i,j;
public:
test(int i_t,int j_t) : i(i_t), j(j_t) {}
};
int main(){
test t(2, 3);
}
- کلیدواژه
register
، در سی پلاس پلاس ۱۷ از سی پلاس پلاس حذف شد.
کتابخانه استاندارد
در سال ۱۹۹۸ استاندارد C++ شامل دو بخش هسته زبان و کتابخانه استاندارد سی++ است. این کتابخانه شامل بیشتر بخشهای STL و کتابخانه استاندارد C است. بیشتر کتابخانههای C++ در استاندارد وجود ندارند یا استفاده از تعریف قابلیت پیوند کتابخانهها را میتوان در زبانهایی مانند فرترن، C، پاسکال، بیسیک نوشته شوند. البته با توجه به ویژگیهای کامپایلر مشخص خواهد شد که کدام زبان را میتوان استفاده نمود.
کتابخانه استاندارد سی++ شامل کتابخانه استاندارد C با یک سری تغییرات برای بهبود عملکرد است. بخش بزرگ بعدی این کتابخانه STL است. STL شامل ابزار بسیار قدرتمندی مانند نگهدارندهها (مانند vector و list)، تکرارکنندهها (اشارهگرهای عمومی شده) برای شبیهسازی دسترسی مانند آرایه الگوریتمهایی برای جستجو و مرتبسازی در آنها وجود دارند. نقشهها (نقشههای چندگانه) (آرایه شرکتپذیر) و مجموعهها (مجموعههای چندگانه) واسطهای عمومی فراهم میسازند. در نتیجه با استفاده از قالب تابع، الگوریتمهای جنریک با هر نگهدارنده و دارای تکرارکننده عمل نماید. همانند C ویژگیهای کتابخانه را میتوان با استفاده از شبه دستور include# شامل یک سرآیند استاندارد اضافه نمود. c دارای ۶۹ کتابخانه استاندارد است که ۱۹ تا از آنها نامناسب تشخیص داده شدهاند.
استفاده از کتابخانه استاندارد - مانند std::vector یا std::string به جای آرایههای C- موجب ایجاد برنامههای مطمئنتر شدهاست.
STL در آغاز محصولی جداگانه از HP و سپس SGL پیش از ادغام در کتابخانه استاندارد C++ بودهاست. استاندارد عبارت STL را بکار نمیبرد بلکه آن را بخشی از کتابخانه میداند اما مردم هنوز هم آن را برای جداسازی بخشهای مختلف کتابخانه با این نام بکار میبرند. (جریانهای ورودی/خروجی، جهانیسازی، تشخیص، زیرمجموعه کتابخانه C)
بیشتر کامپایلرها کتابخانه استاندارد و STL را پیادهسازی مینماید. پیادهسازیهای مستقلی نیز همانند STLport نیر وجود دارند. پروژههای دیگر نیز پیادهسازیهای خود را از STL با توجه به اهداف خود به وجود میآورند.
ویژگیهای معرفی شده در C++
در مقایسه با C زبان C++ ویژگیهای جدیدی را معرفی نمودهاست مانند تعریف متغیر به عنوان عبارت، تغییر نوعهای همانند تابع، نو/حذف، نوع داده bool، توابع درونخطی، آرگومان پیشفرض، گرانبارسازی عملگر و تابع، فضای نام و عملگر تعیین حوزه ::، کلاسها (شامل تمام ویژگیهای مربوط به کلاسها همانند وراثت، اعضای تابع، توابع مجازی، کلاسهای انتزاعی، و سازندهها)، قالبها، پردازش استثناء، کنترل نوع زمان اجرا، عملگرهای سربار شده ورودی (<<) و خروجی (>>).[16]
برخلاف باور عموم C++ نوع داده ثابت را معرفی ننمودهاست. کلمه const کمی پیش از استفاده از این کلمه در C++ توسط زبان C به صورت رسمی بکار گرفته شد.
در بعضی حالات C++ تعداد کنترل نوع بیشتری نسبت به زبان C انجام میدهد. (برای اطلاعات بیشتر بخش «ناهماهنگی با C» را در پایین ببینید)
توضیحات با استفاده از // قبل از زبان C در زبان بیسیپیال معرفی شده بود که مجدداً در زبان C++ به کار گرفته شد.
بعضی ویژگیهای C++ بعداً توسط C به کار گرفته شد مانند نحوه تعریف for، توضیحات به شکل C++ (با استفاده از //)، و کلمه inline با وجود اینکه تعریف این کلمه در C با تعریف آن در زبان C++ هماهنگی ندارد. همچنین در C ویژگیهایی معرفی شدهاست که در C++ وجود ندارند مانند ماکروهای قابل تغییر و استفاده بهتر از آرایهها به عنوان آرگومان. بعضی کامپایلرها این ویژگیها را پیاده نمودهاند اما در بقیه این ویژگیها موجب ناهماهنگی میگردد.
برنامهٔ Hello World
برنامهٔ زیر با استفاده از کتابخانه استاندارد و جریانهای خروجی، یک متن را به خروجی استاندارد ارسال مینماید.
#include <iostream>
int main()
{
std::cout << "Hello, world!" << std::endl; // prints "Hello world!"
}
ویژگیهای زبان
پیش پردازنده
C++ بهطور عمومی در سه فاز ترجمه میگردد: پیشپردازنده، ترجمه به کد object، پیوند (که دو مرحله آخر به عنوان عمل کامپایل شناخته میشود) در اولین مرحله در پیشپردازنده، شبهدستورات پیشپردازنده تغییرات لغوی بر روی کد منبع ایجاد مینمایند و آن را به مراحل دیگر تحویل میدهند.
شبه دستورها پیشپردازنده با استفاده از کاراکتر # قبل از هر گونه فضای خالی آغاز گشته و رشتههایی را در کد منبع با فایل یا رشتههای دیگر با توجه به قوانین تعریف گشته توسط برنامهنویس جایگزین مینماید. این دستورها معمولاً اعمال زیر را انجام میدهند: جایگزینی کلاندستورها، شمول فایلهای دیگر (برخلاف ویژگی سطح بالاتر مانند شمول ماژولها/پکیجها/یونیتها/کامپوننتها)، کامپایل شرطی و/یا شمول شرطی. به عنوان مثال:
#include <iostream>
که این دستور تمام سمبلها در فایل سرایند کتابخانه استاندارد iostream
را در فایل منبع وارد میسازد.
کاربرد معمول دیگر به عنوان کلاندستور (ماکرو) خوانده میشود:
#define MY_ASSERT(x) assert(x)
که کد (MY_ASSERT(x را با (assert(x در فایل منبع جایگزین مینماید؛ که این جایگزینی امکان کنترل استفاده از این تابع را در اختیار برنامهنویس قرار میدهد.
استفاده از ماکروها در عمل چندان توصیه نمیگردد چرا که امکان کنترل نوع آرگومانها را از بین برده در نتیجه ممکن است اشتباهاتی را وارد کد منبع نماید. طریقه دیگر برای انجام این کار استفاده از توابع درونخطی است.
علاوه بر شبهدستورات معمول تعدادی شبه دستور برای کنترل جریان کامپایل وجود دارد که امکان شمول یا عدمشمول قطعهای کد یا سایر ویژگیهای کامپایل را در اختیار ما قرار میدهد.
دستورها پیشپردازنده برای کاربردهای عددی نیز به کار میرود که هماکنون استفاده از const
و enum
به جای #define
ترجیح داده میشود. این کار علاوه بر ایجاد کنترل نوع قوی مانع از گمراهی در فضاهای نام میگردد.
هدف کمیته استانداردسازی از بین بردن پیشپردازندهاست اما با توجه به خصوصیت مدولار C++ بعید به نظر میآید که این حذف امکانپذیر باشد.
پیش پردازنده ifdef و ifndef که برای بررسی کردن اینکه آیا مثلاً کلان دستور x تعریف شدهاست یا نه استفاده میشود برای مثال
#define x 30 //تعریف کلان دستور x که مقدار 30 است
#ifdef x //اگر کلان دستور x تعریف شده بود
#define y 40 //تعریف کلان دستور y با مقدار 40
#endif //پایان شرط
#ifndef x //اگر کلان دستور x تعریف نشده بود
#define x 30 //کلان دستور x را تعریف کن
#endif
پیش پردازنده error برای خطا دادن قبل همگردانی است، مثلاً اگر کلان دستور x تعریف شده بود خطایی نشان میدهد:
#define x 30
#ifdef x
#error "Error x is defined"
#endif
یا پیش پردازنده warning برای هشدار:
#define x 30
#ifdef x
#warning "X is defined!"
#endif
پیش پردازنده ای هم برای تغییر قابلیتهای همگردان یا کامپایلر نیز وجود دارد که pragma نام دارد، مثلاً برای نشان ندادن هشدارها به کار میرود.
قالبها
قالبها متفاوت با ماکروها هستند. در حالی که از هر دوی این ویژگیها در زمان کامپایل برای ایجاد کامپایل شرطی استفاده میشوند قالبها محدود به تغییرات لغوی و متنی نیستند. قالبها با آگاهی از معنا و سیستم نوع در زبان استفاده شده و سایر ویژگیهای زمان کامپایل میتوانند از عملیات سطح بالا برای کنترل ترتیب اجرا براساس نوع پارامترها استفاده نمایند. ماکروها کنترل خود را بر کامپایل از طریق ویژگیهای از پیش تعیین شده انجام میدهند ولی قادر به ایجاد انواع جدید و کنترل نوع نیستند و فقط محدود به تغییرات متنی پیش از کامپایل هستند. به زبان دیگر ماکروها کنترل خود را با استفاده از نشانههای از پیش تعیین شده انجام میدهند اما همانند قالبها نمیتوانند نشانهها را خود ایجاد نمایند. قالبها ابزاری برای چندریختی ایستا و برنامهنویسی جنریک است؛ مثلاً جایگزین معادل با استفاده از قالبها برای عبارت خطرناک #define max(x, y) ((x)> (y) ? (x) : (y))
در پایین نشان داده شدهاست.
template <typename T>
const T& max(const T& x, const T& y)
{
return x > y ? x : y;
}
این قالب در سرآیند algorithm
تحت عنوان std::max()
قابل دسترسی است. معمولاً میتوان از کلمه کلیدی class
بجای typename
استفاده کرد.
علاوه بر این قالبها یک ویژگی تورینگ-کامل هستند که به این معناست که هر برنامه قابل محاسبه توسط کامپیوتر را میتوان با استفاده از فرابرنامهنویسی قالبها نوشت.
بهطور خلاصه استفاده از قالبها به معنای نوشتن هر تابع یا کلاس بااستفاده از تمامی انواعِ ممکن است، که نوع آن را تا پیش از سی پلاس پلاس ۲۰ نمیشد محدود کرد، اما در سی پلاس پلاس ۲۰، با استفاده از مفاهیم قالب میتوان انرا به نوعهای خاصی محدود کرد.
اشیاء
++C چندین ویژگی شیگرا را معرفی نمود، معرفی کلاس چهار ویژگی که در زبانهای شیگرا و بعضاً غیر شیگرا حضور دارد یعنی انتزاع، بستهبندی، وراثت، و چندریختی را فراهم کرد. اشیاء نمونههای ساخته شده از کلاس در زمان اجرا هستند. میتوان کلاس را نمونهای از قالبها دانست که چندین مورد از آنها به وجود میآید.
بستهبندی
بستهبندی به معنای جمعآوری عملیات و داده در یک محل میباشد. ++C بستهبندی را با ایجاد امکان تعریف هر کلاس به صورت public, private, protected پیادهسازی نمودهاست. اعضای private فقط توسط اعضای کلاس یا کلاسها دقیقاً بیان شده (friend) قابل دسترسی هستند. اعضای protected توسط کلاسهای ارث برده شده و اعضای کلاس و کلاسهای friend قابل دسترسی هستند.
در تعاریف شیگرا باید تنها توابعی بستهبندی گردند که باید از نحوه پیادهسازی این نوع بخصوص اطلاع داشته باشد. ++C این ویژگی را با استفاده از توابع عضو و توابع دوست فراهم نموده اما قطعی نکردهاست. در ++C این امکان وجود دارد که تمام نوع را عمومی تعریف نمایند اما در صورتی که نیاز باشد فقط بخشی از آن عمومی گردد در نتیجه این زبان نه تنها شیگرا است بلکه از مدلهای ضعیفتر همانند برنامهنویسی مدولار پشتیبانی مینماید.
عموماً توصیه بر این است که تمام اعضا به صورت خصوصی یا حفاظت شده تبدیل گردند و فقط توابعی که باید توسط دیگر کلاسها به عنوان واسط استفاده شوند عمومی باقی بمانند.
وراثت
وراثت این امکان را ایجاد میکند که یک نوع ویژگی دیگر انواع را داشته باشد. وراثت از یک کلاس پایه میتواند عمومی، خصوصی یا حفاظت شده باشد. این تعیین سطح دسترسی مشخص میسازد آیا کلاسهای نامربوط یا مشتق شده میتوانند به اعضای عمومی یا حفاظت شده کلاس پایه دسترسی داشته باشند. تنها وراثت عمومی به معنای وراثت به کار رفته به صورت عموم است. دو نوع دیگر وراثت به ندرت مورد استفاده قرار میگیرند. اگر تعیینکننده سطح دسترسی حذف شود سطح دسترسی برای کلاس خصوصی و برای ساختمان به صورت عمومی تعریف میگردد. کلاسهای پایه ممکن است به صورت مجازی تعریف شوند که به آن وراثت مجازی گویند. وراثت مجازی تضمین میکند که فقط یک نمونه از کلاس پایه وجود داشته باشد و مشکلاتی همانند مشکلات وراثت چندگانه به وجود نیاید.
وراثت چندگانه یکی از ویژگیهای مورد بحث در ++C است. وراثت چندگانه امکان اشتقاق از چند کلاس پایه را فراهم مینماید که موجب به وجود آمدن گراف رابطه وراثت بسیار پیچیدهاست. به عنوان مثال «گربه پرنده» میتواند از کلاس «گربه» و کلاس «پستانداران پرنده» ارث برد. در زبانهای دیگر مانند سیشارپ و جاوا به صورت دیگری ویژگی مشابه را پیادهسازی مینماید هر کلاس میتواند از چندین واسط اشتقاق یابد اما فقط یک کلاس پایه برای اشتقاق وجود دارد (واسطها برخلاف کلاس پایه فقط تعریف هستند و هیچگونه پیادهسازی را شامل نمیگردند).
چندریختی
امکان استفاده از یک واسط برای چندین پیادهسازی فراهم مینماید و اشیاء در شرایط مختلف رفتار مختلفی از خود نشان میدهند.
++C دو نوع چندریختی در اختیار برنامهنویس قرار میدهد: چندریختی زمان کامپایل و چندریختی زمان اجرا. چندریختی زمان کامپایل امکان تصمیمگیریهای زمان اجرا را فراهم نمیسازد و چندریختی زمان اجرا اغلب موجب پایین آمدن بازدهی میگردد.
چندریختی ایستا
چندریختی ایستا شامل گرانبارسازی تابع، گرانبارسازی عملگر، آرگومان پیشفرض، و قالب کلاسها و تابع است.
چندریختی پویا
چندریختی پویا شامل وراثت و توابع مجازی اعضا است.
گرانبارسازی تابع
گرانبارسازی تابع امکان تعریف چندین تابع با نام یکسان اما با تعداد آرگومانهای متفاوت را فراهم میسازد. این توابع از طریق تعداد پارامترها یا نوع رسمی آنها شناسایی میگردند. در نتیجه یک تابع ممکن است با توجه به موقعیت استفاده معنای مختلفی داشته باشد. نوع داده برگشتی برای تشخیص توابع از یکدیگر مورد استفاده قرار نمیگیرد.
گرانبارسازی عملگر
بهطور مشابه گرانبارسازی عملگر امکان استفاده از یک عملگر مشخص میشود که عملکرد متفاوتی با توجه به عملوندهای خود دارد. این عملگرهای گرانبار شده موجب فراخوانی تابع مشخصی متناسب با آن موقعیت میگردند. گرانبارسازی عملگر ترتیب اجرا یا تعداد عملوندهای یک عملگر را تغییر نمیدهد. عملگرهای . :: .* ?
نمیتوانند گرانبار شوند.
آرگومان پیشفرض
آرگومان پیشفرض در شرایطی به کار میرود که تعیین یک مقدار مشخص برای یک آرگومان نیاز به تعریف یک تابع جدید را برطرف میسازد. هنگام استفاده از این مشخصه باید دقت شود که تابعهای گرانبار شده و تابعهای دارای آرگومان پیشفرض با یکدیگر تداخل نداشته باشند به عنوان مثال:
// function with default argument but also an overloaded function
int strcpy(char* str1, char* str2, short unsigned n = 65535);
// second overloaded function
int strcpy(char* str1, char* str2);
کد بالا در صورت استفاده از یک آرگومان n
برای strcpy
درست کامپایل میگردد اما اگر آرگومانی تعیین نگردد درست عمل نخواهد کرد. چرا که کامپایلر نخواهد دانست که باید از مقدار پیشفرض استفاده نماید یا از تابع بدون آرگومان.
ساختار برنامهها
ساختار برنامهها در این زبان بدین صورت است که همانند زبان سی، هر برنامه بایستی یک تابع اصلی(main) به عنوان بدنه برنامه داشته باشد. هر برنامه معمولاً از تعداد زیادی فایل تشکیل میشود که به هم الحاق میگردند (با دستور include) و به این فایلهای الحاقی، سرآیند (Header) گفته میشود. فایلهای الحاقی حاوی کدها یا نسخههای اجرایی کلاسها (مجموعه متغیرها و توابع) میباشند که در بدنه اصلی برنامه از آنها استفاده میشود. معمولاً هر کلاس (که تعریف یک نوع دادهای با متدهای مربوط به آن است) را در یک سرآیند مینویسند. هر سرآیند که معمولاً تنها تعاریف (معرفی) کلاس را در خود دارد به همراه فایلهای پیادهسازی به زبان C++ یا پیادهسازیهای کامپایل شده (به صورت فایل اشیاء مانند dll یا so یا …) میتواند به کار برده شود. به مجموعههای یکپارچهای از کلاسهای پیادهسازی شده (به صورت فایلهای سرآیند با پیادهسازیهای کد یا اشیای زبان ماشین) که برای برنامهنویسی به کار میروند، یک کتابخانه C++ گفته میشود و قدرت اصلی این زبان در امکان بهکارگیری کتابخانههای آماده میباشد. کتابخانههای بزرگ C++ مانند STL, MFC, QT و … مجموعه قدرتمندی برای تولید برنامه در این زبان ایجاد کردهاند.[17]
نمونه برنامه C++
نمونه ای از ماشین حساب ساده CLI با کتابخانه استاندارد(c++11):
#include <iostream>
struct expr{
expr() = default;
expr(int& v1,char& op,int& v2){
switch(op){
case '-':
std::cout << v1 - v2 << std::endl;
break;
case '+':
std::cout << v1 + v2 << std::endl;
break;
case '*':
std::cout << v1 * v2 << std::endl;
break;
case '/':
std::cout << v1 / v2 << std::endl;
break;
default:
std::cerr << "Operator not found!" << std::endl;
}
}
};
int main(){
int value_1, value_2;
char foperator;
again:
std::cout << "Expr: "<<endl;
std::cin >> value_1 >> foperator >> value_2;
std::expr(value_1, foperator, value_2);
goto again;
}
تست کد C++
برای تست برنامههای نوشته شده با زبان C++ روشهای مختلفی وجود دارد، برخی از ویرایشگرهای مانند visual studio ابزاری برای این منظور دارند ولی برای تست دقیق تر بهتر است از ابزارهای با دقت بالا استفاده کرد، بهینهسازی کد و بالا بردن کارایی از مزیتهای تست کد است. C/C++Test راهکاری یکپارچه برای خودکارسازی محدوده وسیعی از شیوههای تضمین کیفیت برنامههای تولید شده با زبانهای C و C++ میباشد. C/C++Test قابلیت تولید تست واحد (unit test) و تحلیل سورس-کد (static analysis) تحت زبان C++ را داراست. این ابزار امکان خودکارسازی تستهای برنامهنویسی را همراه با اندازهگیری میزان پوشش کد (code coverage) فراهم میسازد. همچنین کیفیت سورس-کد را از ابعاد مختلف کارکردی، کارایی، امنیت و نگهداشت تحلیل میکند. امکان یکپارچه سازی با ابزار SAOTest جهت انجام تست کارکردی و ابزار LoadTest جهت انجام تست کارایی در سطح ماجولهای برنامهنویسی را نیز داراست.[18]
گرانبار سازی
در سی پلاس پلاس گرانبار سازی یکی از مهمترین قابلیتها میباشد. گرانبار سازی در چند حالت توصیف میشود:
گرانبار سازی عملگرها
همانطور که در قبل توضیح داده شد، گرانبار سازی عملگرها اجازه میدهد تا یک عملگر یا اوپراتور را دوباره تعریف کنیم.
-- | ++ | =< | => | > | < |
---|---|---|---|---|---|
^ | % | + | - | / | * |
~ | = | | | || | && | & |
=& | ! | =! | <<
|== |
>> | |
=/ | =% | =^ | =* | =- | =+ |
delete | [] new | new | =| | () | [] |
=>> | =<< | , | *<- | <- | [] delete |
گرانبار سازی توابع
گرانباری سازی توابع، همانطور مانند قبل در پیش هم توضیح مختصری از آن داده شد، به این معناست که میتوان هر تابعی را با آرگومانهای متفاوت دوباره تعریف کرد؛ مانند:
#include <iostream>
void test(){
std::cout << "azmayesh" << std::endl;
}
void test(std::string const& s){
std::cout << s << std::endl;
}
int main(){
test();//azmayesh
test("salam");//salam
}
گرانبار سازی سازندههای کلاس
این نیز مانند گرانبازی سازی توابع است اما کاملاً مربوط به کلاسها میباشد. این قابلیت در کلاسها اجازه میدهند تا چند سازنده را با آرگومانها متفاوت تعریف کنیم؛ برای مثال:
#include <iostream>
class Test{
public:
Test(){
std::cout << "Azmayesh" << std::endl;
};
Test(std::string matn){
std::cout << matn << std::endl;
}
};
int main(){
Test t{"Salam"};//Salam
Test f{};//Azmayesh
}
گرانبار سازی انواع لفظی
این قابلیت در C++11 افزوده شد. در این حالت از گرانبار سازی یک لیترال تایپ یا نوع لفظی توسط برنامهنویس تعریف یا گرانبار سازی میشود؛ مانند:
#include <iostream>
int operator"" _pixel(unsigned long long inch){
return inch * 96;
}//_pixel = int*96
int main(){
int inches = 3_pixel;//3 * 96
std::cout << inches << std::endl;//288
}
حرفهای گسترده
در سیپلاسپلاس، هر حرف ۸ بیت یا یک بایت است. هر حرف ۲۵۶ حالت دارد؛ یعنی فقط حروف اسکی (استاندارد) و چند نشان را میتوانند داشته باشند.
اما حرفهای گسترده یا Wide Characters میتوانند بیش از ۲۵۶ حالت را استفاده کنند و بیش از ۸ بیت هستند.
برای مثال حرف 'à' در نوع دادهٔ char خوانده نمیشود اما در نوع دادهٔ wchar_t، از آنجایی که جدول حروف بزرگتری دارد (۱۶ بیت است) درست نوشته میشود.
البته بهتر است از حروف گسترده استفاده نشود و به جایش از std::string یا رشتهها که یونیکد را پشتیبانی میکنند استفاده شود.
نوع دادههای char16_t و char32_t هم میتوانند جایگزینی برای حروف گسترده باشد.rrrr
تعریف متغیرها
در سیپلاسپلاس، متغیرها به چندین شکل تعریف میشوند؛ مانند:
اولیه سازی یونیفرم {}، کپی =، فراخوانی سازنده ():
int i = 0;
int j{0};
int k(0);
حلقههای for-each
این حلقهها روشی راحتتر برای نوشتن تمامی جزئیات یک دسته هستند. این حلقهها بهعنوان حلقههای بر اساس محدوده نیز یاد میشوند.
مانند:
#include <iostream>
#include <vector>
int main(){
std::vector<std::string> daste = {"D1", "D2", "D3", "D4"};
for(auto& ds : daste){
std::cout << ds;
}
}
جستارهای وابسته
پانویس
منابع
پیوند به بیرون
Wikiwand in your browser!
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.