🔥 أحدث الأخبار

موقع يهتم بكل ماهو جديد في عالم التكنولوجيا والرياضة

كورس C++ المتقدم – الحلقة الثالثة: Smart Pointers (المؤشرات الذكية)


 

كورس 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
  • برمجة احترافية مختصرة وقوية 🚀

تعليقات

💬 🙋🏻‍♂️