سؤال

لقد كنت أفكر في استخدام unique_ptr ضد shared_ptr ضد own_solution.لقد استبعدت الخيار الأخير لأنني سأخطئ بالتأكيد، لكن لدي مشكلة مع كليهما unique_ptr و shared_ptr حيث لا يلتقط أي منهما بالضبط ما أريد.أرغب في إنشاء مدير موارد يمتلك موردًا بشكل صريح، ولكنني أرغب في أن يقوم مدير الموارد أيضًا بتوزيع مراجع للمورد.

إذا كنت تستخدم unique_ptr في مدير الموارد وتوزيع المؤشرات الأولية، هناك احتمال أن يتمكنوا من الهروب إلى مكان آخر (على الرغم من أن هذا سيكون مخالفًا لـ "عقد" الفصل الذي أفترضه).إذا كنت تستخدم shared_ptr وتسليمها weak_ptr, ، لا يوجد ما يمنع المتصل من تحويل weak_ptr إلى أ shared_ptr وتخزين ذلك، وبالتالي من المحتمل إنشاء دورة أو ما هو أسوأ من ذلك، مورد يعيش بعد عمر مدير المورد.لذا أعتقد أن ما أبحث عنه هو أمر قابل للتأجيل weak_ptr التي لا يمكن تحويلها إلى shared_ptr.

أم أنني أتطلع فقط إلى تنفيذ العقد ببعض التعليقات شديدة اللهجة في الكود؟

شكرا على أية أفكار قد تكون لديكم حول هذا الموضوع.

هل كانت مفيدة؟

المحلول

المؤشرات الذكية مثل shared_ptr و unique_ptr هي أدوات جيدة عندما يكون لديك امتلاك مؤشرات.
ولكن بالنسبة للمؤشرات غير المالكة، أي. مراقبة المؤشرات, ، فإن استخدام مؤشر خام أمر جيد.

في تصميمك، أعتقد أن مدير الموارد هو "المالك" الوحيد للموارد، لذلك يمكنك ببساطة الحصول على شكل من أشكال المؤشر الذكي داخل مدير الموارد.على سبيل المثال، يمكن أن يكون لدى مدير الموارد ملف std::vector<std::unique_ptr<Resource>> كعضو بيانات، أو حتى أبسط std::vector<Resource> إذا كان لديك Resource تم تصميم الفئة لتكون قابلة للتخزين بشكل صحيح في ملف std::vector.

بعد ذلك، يمكن لمدير الموارد أن يعطي للخارج فقط مؤشرات مراقبة غير مملوكة، والمؤشرات الأولية (أو مراجع C++) مناسبة لهذه الحالة.

بالطبع، من المهم أن يتجاوز عمر مدير الموارد عمر "عملاء الموارد".

نصائح أخرى

في النهاية، لا يمكنك إجبار أي شخص على الاستماع.اسأل Microsoft أو Apple أو أي مطور مكتبة مفتوحة المصدر، فجميعهم يعرفون تلك الأغنية.التعليق بالكلمات والأماكن المناسبة هو أفضل رهان لك.

تجنب إنشاء فئة المؤشر الذكي الخاصة بك، فهي تعيق التركيب وتقلل من سهولة القراءة.كملاذ أخير، حاول البحث في Boost، أو أي إطار عمل يجب أن تعمل معه التعليمات البرمجية الخاصة بك بالفعل.

إذا لم يكن لديك مالكين، فيمكن اختيارهم للاحتفاظ بهم weak_ptrs أو (إذا كان مضمونًا أن يبقى صالحًا طوال المدة) المؤشرات الأولية.
إذا كنت تستخدم shared_ptrداخليًا (لماذا يجب عليك ذلك)، من الأفضل تقديمه weak_ptr والمؤشرات الخام.

تشير كل هذه المؤشرات الذكية بوضوح إلى سياسة الملكية.تشير المؤشرات الأولية إلى عدم الملكية أو عدم الملكية.

  • auto_ptr:لا تستخدم، إهمال مع الكثير من الفخاخ حتى بالنسبة للحذرين.
  • unique_ptr:الملكية الوحيدة.
  • shared_ptr:ملكية مشتركة
  • weak_ptr:لا توجد ملكية، قد يتم حذفها خلف ظهرك.
  • المؤشر الخام
    • صراحة لا توجد ملكية مع ضمان عمر أكبر
    • أو إدارة الملكية اليدوية.

لذلك أفترض أن ما أبحث عنه هو ضعيف قابلة للتغيير لا يمكن تحويله إلى مشترك.

يمكنك توزيع فصلك المساعد الصغير:

template<typename T>
class NonConvertibleWeakPtr
{
public:
   NonConvertibleWeakPtr(const std::shared_ptr<T>& p) : p_(p) {}
   ... // other constructors / assignment operators
   bool expired() const { return p_.expired(); }
   T* operator->() const { return get(); }
   T& operator*() const { return *get(); }
private:
   T* get() const { return p_.lock().get(); }
private:
   std::weak_ptr<T> p_;
};

وهذا أفضل قليلًا من المؤشر الخام، لأنه يمكنك التحقق مما إذا كان المؤشر لا يزال صالحًا.

مثال على الاستخدام:

std::shared_ptr<int> sp = std::make_shared<int>(5);
{
    NonConvertibleWeakPtr<int> wp(sp);
    if(!wp.expired()) {
        std::cout << *wp << std::endl;
    }
}

ومع ذلك، لا يزال من الممكن للمستخدم إساءة استخدامه على سبيل المثال مع std::shared_ptr<T> blah(&(*wp));, ، لكن الأمر يتطلب المزيد من الطاقة الإجرامية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top