عندما كنت استخدام std::auto_ptr بدلا من دفعة::shared_ptr?
-
22-07-2019 - |
سؤال
لدينا الى حد كبير انتقلت إلى استخدام boost::shared_ptr
في كل من التعليمات البرمجية ، ومع ذلك لا يزال لدينا بعض حالات معزولة حيث نستخدم std::auto_ptr
, ، بما في ذلك المفرد فصول:
template < typename TYPE >
class SharedSingleton
{
public:
static TYPE& Instance()
{
if (_ptrInstance.get() == NULL)
_ptrInstance.reset(new TYPE);
return *_ptrInstance;
}
protected:
SharedSingleton() {};
private:
static std::auto_ptr < TYPE > _ptrInstance;
};
لقد قيل لي أن هناك سبب وجيه جدا لماذا لم يكن هذا جعل shared_ptr
, لكن بالنسبة لي لا أستطيع أن أفهم لماذا ؟ وأنا أعلم أن auto_ptr
سوف تحصل في نهاية المطاف علامة انخفضت في مستوى المقبل, لذا أود أن تعرف ما/كيف يمكنني استبدال هذا التنفيذ.
أيضا, هل هناك أي أسباب أخرى لماذا النظر في استخدام auto_ptr
بدلا من shared_ptr
? و هل ترى أي مشاكل الانتقال إلى shared_ptr في المستقبل ؟
تحرير:
- وذلك في جواب "هل يمكنني استبدال بأمان
auto_ptr
معshared_ptr
في التعليمات البرمجية أعلاه", الجواب هو نعم ولكن سآخذ صغير ضرب الأداء. - عندما
auto_ptr
هو في نهاية المطاف علامة انخفضت و ننتقل إلىstd::shared_ptr
, سوف تحتاج إلى اختبار دقيق رمز لنا للتأكد من أننا الالتزام ملكية مختلفة دلالات.
المحلول
auto_ptr
و shared_ptr
حل مشاكل مختلفة تماما.لا محل الآخر.
auto_ptr
هو غلاف رقيق حول مؤشرات لتنفيذ RAII دلالات ، بحيث الموارد أصدرت دائما, حتى عندما تواجه استثناءات. auto_ptr
لا تؤدي أي إشارة العد أو ما شابه ذلك في كل شيء ، لا تجعل متعددة مؤشرات تشير إلى نفس الكائن عند إنشاء نسخة.في الواقع الأمر مختلف جدا. auto_ptr
هي واحدة من عدد قليل من الطبقات حيث عامل التعيين يعدل المصدر الكائن.النظر في هذا وقح المكونات من auto_ptr صفحة ويكيبيديا:
int *i = new int;
auto_ptr<int> x(i);
auto_ptr<int> y;
y = x;
cout << x.get() << endl; // Print NULL
cout << y.get() << endl; // Print non-NULL address i
لاحظ كيف المنفذة
y = x;
يعدل ليس فقط y ولكن أيضا x.
على boost::shared_ptr
قالب يجعل من السهل التعامل مع مؤشرات متعددة إلى نفس الكائن ، والهدف من ذلك هو فقط المحذوفة بعد آخر إشارة إلى أنها خرجت من نطاق.هذه الميزة ليست مفيدة في السيناريو الخاص بك ، (محاولات) تنفيذ المفرد.في السيناريو الخاص بك, هناك دائما إما 0 المراجع 1 الإشارة إلى الكائن الوحيد من الطبقة ، إن وجدت.
في جوهرها ، auto_ptr
الكائنات shared_ptr
كائنات مختلفة تماما دلالات (لهذا السبب لا يمكنك استخدام السابق في حاويات ، ولكن القيام بذلك مع هذا الأخير على ما يرام), و آمل أن تكون لديك اختبارات جيدة للقبض على أي الانحدارات كنت أدخلت في حين ترقية التعليمات البرمجية الخاصة بك.:-}
نصائح أخرى
الآخرين قد أجبت لماذا هذا الرمز يستخدم auto_ptr
بدلا من shared_ptr
.إلى العنوان الخاص بك الأسئلة الأخرى:
ما/كيف يمكنني استبدال هذا التنفيذ ؟
استخدم boost::scoped_ptr
أو unique_ptr
(متوفر في كل دفعة جديدة C++ القياسية).سواء scoped_ptr
و unique_ptr
توفير صارمة ملكية (أي إشارة العد النفقات العامة) ، وأنها تجنب المستغرب حذف-على-نسخة دلالات auto_ptr
.
أيضا, هل هناك أي أسباب أخرى لماذا النظر في استخدام auto_ptr
بدلا من shared_ptr
?و هل ترى أي مشاكل الانتقال إلى shared_ptr
في المستقبل ؟
شخصيا, وأود أن لا تستخدم auto_ptr
.حذف على نسخ جدا فقط غير بديهية. عشب ساتر يبدو أن نتفق.التحول إلى scoped_ptr
, unique_ptr
, أو shared_ptr
يجب أن نقدم أي مشاكل.على وجه التحديد ، shared_ptr
يجب أن تكون قطرة في استبدال إذا كنت لا تهتم حول المرجعية عد النفقات العامة. scoped_ptr
هو قطرة في استبدال إذا كنت لا تستخدم auto_ptr
's نقل ملكية القدرات.إذا كنت تستخدم نقل الملكية ، ثم unique_ptr
هو تقريبا قطرة في استبدال, إلا أن تحتاج بدلا من ذلك بشكل صريح استدعاء move
نقل الملكية.انظر هنا على سبيل المثال.
auto_ptr هو النوع الوحيد من مؤشر ذكية يمكنني استخدام.أنا استخدامها لأنني لا استخدم دفعة ، و لأنني يفضلون عموما عملي/تطبيق المنحى دروس صراحة تعريف الحذف دلالات والنظام بدلا من الاعتماد على مجموعات أو فرادى, المؤشرات الذكية.