shared_ptr vs scoped_ptr
-
21-09-2019 - |
سؤال
scoped_ptr
ليس نسخة قادرة ويتم حذفها خارج النطاق. لذلك فهو مقيد shared_ptr
. لذلك يبدو إلى جانب الحالات التي تحتاج فيها حقًا إلى تقييد عملية النسخ shared_ptr
من الأفضل الاستخدام. لأنه في بعض الأحيان لا تعرف أنك بحاجة إلى إنشاء نسخة من كائنك أو لا. لذا فإن السؤال هو: إلى جانب الحالات المذكورة أعلاه ، هل يمكننا التفكير في ذلك shared_ptr
من الأفضل (أو الموصى بها) الاستخدام بدلاً من scoped_ptr
. يفعل scoped_ptr
العمل أسرع بكثير من shared_ptr
, ، أم أنها لها أي مزايا؟
شكرًا!
المحلول
shared_ptr
هو وزن ثقيل أكثر من scoped_ptr
. يحتاج إلى تخصيص كائن عدد مرجعي وتحريره وكذلك الكائن المدار ، والتعامل مع العد المرجعي لأمان مؤشر الترابط - على منصة واحدة عملت عليها ، كان هذا بمثابة عام كبير.
نصيحتي (بشكل عام) هي استخدام أبسط كائن يلبي احتياجاتك. إذا كنت بحاجة إلى مشاركة مرجعية ، فاستخدم shared_ptr
; ؛ إذا كنت بحاجة فقط إلى الحذف التلقائي بمجرد الانتهاء من مرجع واحد ، فاستخدم scoped_ptr
.
نصائح أخرى
أداء - shared_ptr
لديه المزيد من الوظائف ، ولكنه يتطلب أيضًا تخصيصًا إضافيًا (إنه أكبر أيضًا ، ولكن نادرًا ما يهم).
تحرير] يمكن تجنب التخصيص الثاني باستخدام make_shared
, ، ولكن بعد ذلك weak_ptr
سيحمل التخصيص بأكمله حتى بعد تدمير الكائن ، والذي قد يمثل مشكلة للكائنات الكبيرة.
Expresison من النية استخدام scoped_ptr
أنت توضح بشكل أكثر صراحة ما تريد القيام به. (في حال كنت تتساءل - هذا شيء جيد :)). إذا قمت بذلك بشكل صحيح ، فسيشير Servent_ptr أيضًا إلى "هذا الكائن يهدف إلى العيش خارج هذا النطاق"
الغرض المقصود مختلف ، لذلك ، في كثير من الحالات ، "shared_ptr vs scoped_ptr" ليس سؤالًا على الإطلاق. بالتأكيد ، يمكنك استخدام shared_ptr عندما يكون كل ما تحتاجه هو scoped_ptr. لكن ما هي النقطة؟ من المحتمل أن يكون لدى Servent_ptr أن النفقات العامة أكبر قليلاً مع كل المرجع المعني.
scoped_ptr
يعمل بشكل أسرع بكثير من shared_ptr
. هذا صحيح. shared_ptr
قم دائمًا بتخصيص الذاكرة باستخدام مخصصك أو تخصيصه الافتراضي.
لا يشترك SCOPED_PTR إلى القليل من المشترك مع shared_ptr أو pear_ptr أو فريدة من نوعها لأنها تقوم فقط بحالة خاصة جدًا من "العد المرجعي". إنه ليس شيئًا ستحتاجه كثيرًا في رمز مصمم جيدًا ، ولكنه أداة جيدة لتتوفرها.
في الأساس ، فإن SCOPED_PTR ليس شيئًا مرجعيًا على الإطلاق. بدلاً من ذلك ، إنه كائن تقوم بإنشائه على المكدس (ضمن النطاق المحلي) بحيث يمكنك فعل شيء مثل هذا:
//Some enclosing scope- anything set off by "{}" or even a function:
{
scoped_ptr<MyObject> ptr = new MyObject( parameters...);
} // When we hit this closing brace, "ptr" will delete the "MyObject" inside.
تميل إلى رؤية هذا النمط أكثر مع Mutexes وغيرها من مباريات المزامنة- يمكنني إعلان "Autolock" الذي سيغلق المطفلة التي تم تمريرها فيها ، ثم فتحه عندما يحذف نطاق تحويل "{}" إلى قسم مهم.
لاحظ أيضًا أن "scoped_ptr" لا معنى له إلا عندما لا يمكنك القيام بتخصيص مكدس قديم مثل "myobject obj (params ..)" لسبب ما. بعد كل شيء ، ما تفعله هو السماح لك باستخدام كائن مخصص للكومة كما لو كان على المكدس. هذا يميل إلى أن يكون نادرًا كثيرًا من حالة الاستخدام من التخصيص المرجعي لـ shared_ptr وأبناء عمها.