لماذا من الخطأ استخدام std::auto_ptr<> مع الحاويات القياسية؟

StackOverflow https://stackoverflow.com/questions/111478

سؤال

لماذا من الخطأ استخدامه std::auto_ptr<> مع الحاويات القياسية؟

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

المحلول

يقول معيار C ++ أنه يجب أن يكون عنصر STL "قابل للإنشاء" و "قابل للتخصيص". بمعنى آخر ، يجب أن يكون العنصر قادرًا على تعيينه أو نسخه والعنلين مستقلان منطقيا. std::auto_ptr لا يفي بهذا المطلب.

خذ على سبيل المثال هذا الكود:

class X
{
};

std::vector<std::auto_ptr<X> > vecX;
vecX.push_back(new X);

std::auto_ptr<X> pX = vecX[0];  // vecX[0] is assigned NULL.

للتغلب على هذا القيد، يجب عليك استخدام std::unique_ptr, std::shared_ptr أو std::weak_ptr المؤشرات الذكية أو معادلاتها المعززة إذا لم يكن لديك C++ 11. فيما يلي وثائق المكتبة المعززة لهذه المؤشرات الذكية.

نصائح أخرى

ال دلالات النسخ ل auto_ptr غير متوافقة مع الحاويات.

على وجه التحديد، نسخ واحد auto_ptr إلى آخر لا يُنشئ كائنين متساويين نظرًا لأن أحدهما فقد ملكيته للمؤشر.

وبشكل أكثر تحديدًا، نسخ ملف auto_ptr يؤدي إلى ترك إحدى النسخ للمؤشر.لم يتم تحديد أي منها يبقى في الحاوية.لذلك، من الممكن أن تفقد الوصول إلى المؤشرات بشكل عشوائي إذا قمت بتخزينها auto_ptrs في الحاويات.

مقالتان ممتازتان للغاية حول هذا الموضوع:

يجب أن تكون حاويات STL قادرة على نسخ العناصر التي تخزنها فيها، وهي مصممة بحيث تتوقع أن تكون النسخة الأصلية والنسخة متساويتين.تمتلك كائنات المؤشر التلقائي عقدًا مختلفًا تمامًا، حيث يؤدي النسخ إلى نقل الملكية.وهذا يعني أن حاويات auto_ptr ستظهر سلوكًا غريبًا، اعتمادًا على الاستخدام.

يوجد وصف تفصيلي لما يمكن أن يحدث من خطأ في البند 8 من STL الفعال (سكوت مايرز) وأيضًا وصف غير مفصل في البند 13 من C++ الفعال (سكوت مايرز).

تقوم حاويات STL بتخزين نسخ من العناصر المضمنة.عندما يتم نسخ auto_ptr، فإنه يضبط ptr القديم على قيمة خالية.يتم تعطيل العديد من أساليب الحاوية بسبب هذا السلوك.

معيار C++03 (ISO-IEC 14882-2003) يقول في البند 20.4.5 الفقرة 3:

[...] [ملحوظة:...] لا تفي AUTO_PTR بالمتطلبات القابلة للنسخ القابلة للتقليط والقابل للتخصيص لعناصر حاوية المكتبة القياسية ، وبالتالي وضع حاوية مكتبة قياسية مع AUTO_PTR يؤدي إلى سلوك غير محدد.- ملاحظة النهاية]

معيار C++11 (ISO-IEC 14882-2011) يقول في الملحق D.10.1 الفقرة 3:

[...] ملحوظة:...] مثيلات Auto_Ptr تلبي متطلبات MovEconstructactible و MoveAsissign ، ولكن لا تفي بمتطلبات القابلة للنسخ والنسخ.— ملاحظة النهاية ]

معيار C++14 (ISO-IEC 14882-2014) يقول في الملحق C.4.2 الملحق D:ميزات التوافق:

يتغير:قوالب الفئة Auto_ptr و Unary_Function و Binary_Function ، يتم تحديد قوالب الوظيفة العشوائية ، وقوالب الوظيفة (وأنواع الإرجاع الخاصة بهم) ptr_fun ، mem_fun ، mem_fun_ref ، bind1st ، و bind2nd.
الأساس المنطقي:تم استبداله بميزات جديدة.
التأثير على الميزة الأصلية:قد تفشل رمز C ++ 2014 الصحيح الذي يستخدم قوالب الفئة هذه وقوالب الوظائف في تجميعها في هذا المعيار الدولي.

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