كورس C++ المتقدم – الحلقة الثالثة: Smart Pointers (المؤشرات الذكية)
#برمجة
مقدمة
مرحباً بك في الحلقة الثالثة من المستوى المتقدم في C++.
في الحلقات السابقة تعلمنا:
- Templates
- Exception Handling
واليوم سندخل موضوع مهم جداً في C++ الحديثة:
Smart Pointers
وهي بديل آمن لـ:
new
delete
لماذا نحتاج Smart Pointers؟
في الذاكرة الديناميكية كنا نكتب:
int* p = new int;
*p = 10;
delete p;
المشكلة
إذا نسيت:
delete p;
سيحدث:
Memory Leak
أي تسرب في الذاكرة.
الحل: Smart Pointers
Smart Pointer هو مؤشر ذكي:
✔ يحجز الذاكرة تلقائياً
✔ يحذفها تلقائياً
✔ يمنع الأخطاء الشائعة
أنواع Smart Pointers
في C++ توجد 3 أنواع رئيسية:
| النوع | الوظيفة |
|---|---|
| unique_ptr | مالك واحد فقط |
| shared_ptr | عدة مالكين |
| weak_ptr | مراقبة بدون ملكية |
أولاً: unique_ptr
فكرة بسيطة
كائن له مالك واحد فقط
مثال
#include <iostream>
#include <memory>
using namespace std;
int main()
{
unique_ptr<int> p(new int(10));
cout << *p;
return 0;
}
ماذا حدث؟
- تم إنشاء ذاكرة
- لم نستخدم delete
- تم حذفها تلقائياً عند نهاية البرنامج
طريقة أفضل (حديثة)
auto p = make_unique<int>(20);
مثال كامل
#include <iostream>
#include <memory>
using namespace std;
int main()
{
auto p = make_unique<int>(50);
cout << *p << endl;
return 0;
}
مميزات unique_ptr
✔ بسيط
✔ آمن
✔ سريع
✔ لا يسمح بالنسخ
خطأ شائع
unique_ptr<int> p1 = make_unique<int>(10);
unique_ptr<int> p2 = p1; // خطأ
السبب
unique_ptr لا يسمح بوجود مالكين لنفس الذاكرة.
ثانياً: shared_ptr
فكرة
عدة مؤشرات يمكنها مشاركة نفس الذاكرة
مثال
#include <iostream>
#include <memory>
using namespace std;
int main()
{
shared_ptr<int> p1 = make_shared<int>(100);
shared_ptr<int> p2 = p1;
cout << *p1 << endl;
cout << *p2 << endl;
return 0;
}
ماذا يحدث؟
- p1 و p2 يشيران لنفس المكان
- الذاكرة تحذف عند انتهاء الجميع
عداد المراجع (Reference Count)
p1 → 1
p2 → 2
عند خروج الجميع:
0 → حذف الذاكرة
مثال عملي
#include <iostream>
#include <memory>
using namespace std;
int main()
{
shared_ptr<int> a = make_shared<int>(30);
{
shared_ptr<int> b = a;
cout << *b << endl;
}
cout << *a << endl;
return 0;
}
مميزات shared_ptr
✔ مشاركة البيانات
✔ إدارة تلقائية للذاكرة
✔ مناسب للأنظمة الكبيرة
ثالثاً: weak_ptr
المشكلة
shared_ptr قد يسبب:
Circular Reference
مثال مشكلة
A → B
B → A
الذاكرة لا تُحذف أبداً
الحل: weak_ptr
فكرة
مراقبة بدون امتلاك
مثال
#include <iostream>
#include <memory>
using namespace std;
int main()
{
shared_ptr<int> sp = make_shared<int>(100);
weak_ptr<int> wp = sp;
cout << *sp << endl;
return 0;
}
استخدام weak_ptr
لا يمكن استخدامه مباشرة
يجب تحويله:
auto temp = wp.lock();
if(temp)
{
cout << *temp;
}
مقارنة الأنواع
| النوع | الملكية | النسخ | الاستخدام |
|---|---|---|---|
| unique_ptr | واحد | لا | بسيط |
| shared_ptr | متعدد | نعم | مشاريع كبيرة |
| weak_ptr | لا | نعم | مراقبة |
مثال عملي: إدارة كائن
#include <iostream>
#include <memory>
using namespace std;
class User
{
public:
string name;
User(string n)
{
name = n;
}
void show()
{
cout << name << endl;
}
};
int main()
{
unique_ptr<User> u1 = make_unique<User>("Ahmed");
u1->show();
return 0;
}
لماذا Smart Pointers مهم؟
✔ يمنع تسرب الذاكرة
✔ يقلل الأخطاء
✔ يجعل الكود احترافي
✔ يستخدم في STL الحديثة
أين تستخدم Smart Pointers؟
- الألعاب
- الأنظمة الكبيرة
- الذكاء الاصطناعي
- محركات البرمجة
- مكتبات C++ الحديثة
أخطاء شائعة
❌ استخدام delete مع Smart Pointer
❌ نسخ unique_ptr
❌ استخدام weak_ptr بدون lock()
تمرين 1
أنشئ unique_ptr يخزن رقم ويطبعه.
تمرين 2
أنشئ shared_ptr ونسخه لمؤشرين.
تمرين 3
جرّب weak_ptr مع shared_ptr.
تمرين 4
اصنع كلاس User باستخدام Smart Pointer.
تمرين 5
أنشئ نظام بسيط لإدارة طلاب باستخدام shared_ptr.
ملخص الحلقة الثالثة
تعلمنا:
- unique_ptr
- shared_ptr
- weak_ptr
- make_unique
- make_shared
- Reference Counting
- إدارة الذاكرة الحديثة
- منع Memory Leaks
في الحلقة الرابعة سنتعلم:
🔥 Lambda Functions (الدوال المجهولة)
وسنتعرف على:
- كتابة دوال بدون اسم
- استخدامها مع STL
- sort مع lambda
- for_each
- برمجة احترافية مختصرة وقوية 🚀

تعليقات
إرسال تعليق