std::shared_ptr
المؤشّر الذكي المشترك std::shared_ptr
std::shared_ptr مؤشّر ذكي يسمح لعدة مالكين بمشاركة نفس الكائن، عبر عدّاد مراجع يحرّر الذاكرة تلقائيًا عند وصوله للصفر.
على عكس unique_ptr الحصري، shared_ptr يسمح بتعدد المالكين لنفس الكائن على الكومة: كل نسخة shared_ptr جديدة تزيد عدّاد مراجع داخليًا (reference count)، وكل هادم ينقصه، وعند وصول العدّاد للصفر (آخر مالك يخرج من نطاقه) يُحرَّر الكائن تلقائيًا. مناسب لهياكل بيانات معقّدة يشترك فيها أكثر من جزء من البرنامج بنفس الكائن دون وضوح من يملكه أولًا.
المقابل: تكلفة أداء إضافية بسيطة (زيادة/نقصان العدّاد بأمان بين الخيوط)، وخطر تسريب ذاكرة لو تشكّلت دورة مراجع (كائنان يشير كل منهما للآخر بـ shared_ptr) — يُحل هذا بـ std::weak_ptr.
الصياغة
std::shared_ptr<Type> p = std::make_shared<Type>(args);
📄 مثال
#include <memory>
std::shared_ptr<int> a = std::make_shared<int>(42);
std::cout << a.use_count(); // 1
{
std::shared_ptr<int> b = a; // نسخ مسموح، العدّاد يصبح 2
std::cout << a.use_count(); // 2
} // b يخرج من النطاق، العدّاد يعود لـ 1
std::cout << a.use_count(); // 1أهم النقاط
| العنصر | الوظيفة |
|---|---|
| std::make_shared<T>(args) | إنشاء آمن وأكفأ من new مباشرة (تخصيص واحد للكائن وعدّاد المراجع معًا) |
| use_count() | يُرجع عدد المالكين الحاليين للكائن — مفيد للتصحيح فقط، ليس للمنطق |
| النسخ (=) | مسموح تمامًا، ويزيد عدّاد المراجع بأمان (thread-safe للعدّاد نفسه) |
💡 نصائح عملية
- استخدم shared_ptr فقط لما تحتاج فعليًا ملكية مشتركة حقيقية — إن كان مالك واحد يكفي، unique_ptr أخف وأوضح
- لكسر دورات المراجع (كائنان يشيران لبعضهما)، استخدم std::weak_ptr لأحد الطرفين
⚠️ أخطاء شائعة
- استخدام shared_ptr افتراضيًا بكل مكان بدل unique_ptr — تكلفة أداء غير ضرورية حين لا توجد ملكية مشتركة فعلية
- إنشاء shared_ptr من نفس المؤشّر الخام مرتين بشكل منفصل — يُنشئ عدّادي مراجع مستقلّين ويسبب حذفًا مزدوجًا
خصائص ذات صلة
🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار CPP الكامل بالعربي.