از Python به C++: چرا فاصلهی بین آنها بیشتر از حد انتظار است
نگاهی عملی به این موضوع که چرا انتقال از Python به C++ مردم را گیج میکند، و آنچه برای یادگیری آن باید روی آن تمرکز کنید.
هر برنامهنویس Python که برای اولین بار C++ را لمس میکند همان واکنش را دارد: چرا چاپ "hello world" به این مقدار مراسم نیازمند است؟ پرش فقط نحو نیست. این تغییری است در نحوهی فکر کردن شما دربارهی حافظه، انواع دادهها، و آنچه کامپیوتر واقعاً در حین اجرای برنامه شما انجام میدهد.
آنچه Python از شما پنهان کرده بود
Python روی یک مفسر (CPython، در بیشتر موارد) کار میکند که تخصیص حافظه، جمعآوری زباله، و بررسی نوع را در پشت صحنه مدیریت میکند. وقتی x = 5 را بنویسید و بعداً x = "hello" را، Python فقط شانه بالا میاندازد و نام را دوباره اختصاص میدهد. بدون شکایت، بدون پاکسازی که شما بخشی از آن باشید.
C++ این کار را برای شما انجام نمیدهد. وقتی int x = 5; را بنویسید، شما یک قطعهی ثابتی از حافظه را به اندازهی یک عدد صحیح رزرو کردهاید. بعداً نمیتوانید یک رشته را در آن بریزید. و وقتی حافظه را بهطور پویا با new اختصاص میدهید، شما مسئول انتشار آن با delete هستید — اگر فراموش کنید، یک نشت حافظه دارید. اگر فراموش کنید که بررسی کنید یک اشارهگر null است قبل از آن که آن را بررسی کنید، یک segfault دارید. Python عملکرد را در برابر شبکه ایمنی معامله میکند. C++ شما را قیچی میدهد و به شما اعتماد میکند که بدون دویدن.
تایپ استاتیک نحوهی نوشتن کد را تغییر میدهد، نه فقط نحوهی اعلام متغیرها
در Python، امضاهای تابع پیشنهادها هستند. در C++، آنها قراردادهایی هستند که در زمان کامپایل اجرایی میشوند:
int add(int a, int b) {
return a + b;
}
add(3, "four") را فراخوانی کنید و کامپایلر شما را قبل از اینکه برنامه هرگز اجرا شود متوقف میکند. Python خوشحالانه به شما اجازه میدهد def add(a, b): return a + b را بنویسید، سپس در زمان اجرا به محض اینکه کسی انواع ناسازگاری را در آن وارد کند منفجر میشود. این یک ناراحتی جزیی نیست — این فلسفهی متفاوتی است دربارهی زمانی که خطاها باید ظاهر شوند. C++ میخواهد شما خطاها را در زمان کامپایل بگیرید. Python خوب است اگر آنها را در تولید بگیرید اگر تست نوشته نباشید.
مدیریت حافظه برنامهی درسی واقعی است
بزرگترین پرش مفهومی یادگیری تفاوت stack و heap است. متغیرهای محلی و پارامترهای تابع معمولاً روی stack زندگی میکنند، و هنگام برگشت یک تابع خود را بهطور خودکار پاک میکنند. هر چیزی که با new ایجاد شود روی heap زندگی میکند، و تا زمانی که آن را بهطور صریح با delete حذف کنید یا در یک اشارهگر هوشمند بپیچید، آنجا باقی میماند.
C++ مدرن (C++11 به بعد) برای شما std::unique_ptr و std::shared_ptr میدهد، خصوصاً برای اینکه شما اغلب اوقات مجبور نباشید اشارهگرهای خام را با دست مدیریت کنید:
std::unique_ptr<int> ptr = std::make_unique<int>(42);
این شی خود را هنگام خروج از scope نابود میکند — بدون نیاز به delete دستی. اگر در سال 2024 C++ را یاد میگیرید، مستقیم به اشارهگرهای هوشمند و الگوهای RAII (Resource Acquisition Is Initialization) بروید، بهجای رفتن از تمرینهای حسابی اشارهگر خام که برای برنامهی درسی 1998 بود. شما همچنان نیاز دارید اشارهگرها را بهطور مفهومی بفهمید، اما نیاز ندارید کد malloc/free بنویسید تا آن را ثابت کنید.
کامپایل یک حلقهی بازخورد متفاوت است
Python بازخورد فوری میدهد: اسکریپت را اجرا کنید، خطا را ببینید، آن را درست کنید، دوباره اجرا کنید. C++ یک مرحلهی کامپایل در میان وارد میکند، و این مرحله کل دستهی خطاهایی را میگیرد که Python به زمان اجرا معوق میکند. کامپایل کردن با g++ -Wall -Wextra program.cpp -o program و توجه به هر هشدار ساعتهای سردرگمی در اشکالزدایی را ذخیره میکند. عدم تطابق نوع، متغیرهای غیر آغاز شده، و مسائل مقایسهی علامتدار/بدون علامت همهی اینجا ظاهر میشوند بهجای رفتار اجرایی مرموز. معامله این است که سرعت تکرار کمتر است: حلقهی ویرایش-کامپایل-اجرای شما نسبت به حلقهی ویرایش-اجرای Python آهستهتر است، خصوصاً روی پایگاههای کد بزرگتر جایی که یک بازسازی کامل میتواند دقیقهای طول بکشد. این بخشی از دلیلی است که ابزارهایی مانند ccache و بازسازیهای تدریجی از طریق CMake اهمیت دارند هنگامی که پروژههای شما از چند فایل فراتر میروند.
جایی که این در عمل اهمیت دارد
شما C++ را نمیآموزید برای نوشتن برنامههایی که در Python نوشتید، سریعتر. شما آن را یاد میگیرید زیرا برخی از مسائل به آن نیاز دارند: موتورهای بازی با بودجههای فریم سخت، سیستمهای جاسازیشده با کیلوبایت RAM، سیستمهای معاملات فرکانس بالا جایی که میکروثانیهها هزینهی پول دارند، یا اجزای سیستم عامل که زیر مفسر خود Python نشستهاند. اگر کار امنیتی انجام میدهید، درک مدل حافظه C++ همچنین مستقیماً توضیح میدهد چگونه buffer overflows و use-after-free vulnerabilities در سطح باینری اتفاق میافتند — دانشی که انتزاعات Python فعالانه از شما پنهان میکنند.
توصیهی صادقانه: سعی نکنید C++ را احساس دهید مثل Python. برای مدتی ناراحت بماند. ناراحتی نقطه است — به شما یاد میدهد مفسر Python شما به نمایندگی شما کل این زمان چه کار کرده است.
اگر این نوع مقایسهی زبانبهزبان مفید است، Korra Studio بخشهای مرتبطی در امنیت حافظه، اصول برنامهنویسی سیستم، و معکوسسازی دارد که دقیقاً روی این مفاهیم ساخته شدهاند.
با کمک هوش مصنوعی نوشتهشده، بازبینی و منتشرشده توسط Michal Pilch (CISSP)، Korra Studio.
این یکی از یادداشتهای پایگاه دانش Korra Studio است — پلتفرم هر موضوع را با مربی یکبهیک جفت میکند.
شروع رایگانarrow_forward