سؤال

ممكن مكررة:
كيفية الافراج عن مؤشر من دفعة :: Shared_ptr؟

تقوم وظيفة واجهة بلدي بإرجاع مؤشر إلى كائن. من المفترض أن يكون المستخدم ملكية هذا الكائن. لا أريد إرجاع Boost.Shared_ptr، لأنني لا أريد إجبار العملاء على استخدام دفعة. ومع ذلك، فذلك، أود أن أخزن المؤشر في Shared_Ptr لمنع تسرب الذاكرة في حالة الاستثناءات وما إلى ذلك. يبدو أنه لا توجد وسيلة لفصل مؤشر من مؤشر مشترك. أي أفكار هنا؟

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

المحلول

ما كنت تبحث عن هو release وظيفة؛ shared_ptr ليس لديك وظيفة الإصدار. لكل دليل دفعة:

س: لماذا لا يقدم Shared_ptr وظيفة الإصدار ()؟

لا يستطيع A. Shared_PTR التخلي عن الملكية إلا إذا كان فريدا () لأن النسخة الأخرى ستظل تدمير الكائن.

انصح:

shared_ptr<int> a(new int);
shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2

int * p = a.release();

// Who owns p now? b will still call delete on it in its destructor.

علاوة على ذلك، سيكون من الصعب معالجة المؤشر الذي تم إرجاعه بواسطة الإصدار () بشكل موثوق، حيث كان من الممكن إنشاء المصدر Shared_ptr مع DICELTRETER.

خياران قد تفكر فيه:

  • يمكنك استخدام std::tr1::shared_ptr, ، والتي ستطلب لمستخدمي استخدام تطبيق مكتبة C ++ يدعم TR1 أو لاستخدام دفعة؛ على الأقل هذا من شأنه أن يمنحهم الخيار بين الاثنين.
  • يمكنك تنفيذ الخاصة بك boost::shared_ptr- مثل المؤشر المشترك واستخدام ذلك على واجهاتك الخارجية.

قد تنظر أيضا إلى المناقشة في هذا السؤال حول باستخدام دفعة :: Shared_ptr في الواجهة العامة للمكتبة.

نصائح أخرى

هناك دائما وسيلة :-)

هناك بالفعل سبب لعدم توفر طريقة للإفراج ()، لكن ليس من المستحيل إنشاء واحد. اجعل المساند الخاص بك. شيء على خط (لم تقم بالفعل بتجميع التعليمات البرمجية، ولكن هذه هي الفكرة العامة):

template <typename T>
class release_deleter{
public:
  release_deleter() : released_(new some_atomic_bool(false)){}
  void release() {released_->set(true);}
  void operator()(T* ptr){if(!released_->get()) delete ptr;}
private:
  shared_ptr<some_atomic_bool> released_;
}

..

shared_ptr<some_type> ptr(new some_type, release_deleter<some_type>());

..

release_deleter<some_type>* deleter = get_deleter<release_deleter<some_type>>(ptr);
deleter->release();
some_type* released_ptr = ptr.get();

من المفترض أن يكون المستخدم ملكية هذا الكائن. أنا لا أريد إرجاع boost.shared_ptr،

shared_ptr يعبر مشترك الملكية، وتريد واجهةك للتعبير نقل من الملكية. std::auto_ptr وبالتالي سيكون أكثر قابلية للتطبيق هنا.

ومع ذلك، أود أن أخزن المؤشر في Shared_ptr لمنع تسرب الذاكرة في حالة الاستثناءات

تكرارا، shared_ptr قد لا تكون أفضل أداة لهذه الوظيفة. لمنع التسريبات في حالة الاستثناءات، scoped_ptr أو auto_ptr سيكون مناسبا أفضل.

إستخدم shared_ptr إلى أ scoped_ptr إلى المورد (shared_ptr<scoped_ptr<Resource>>). بهذه الطريقة تحصل عليه shared_ptrالعد المرجعي، الذي سيقوم بتدمير المورد تلقائيا إذا وفقط إذا كان لا يزال مرتبطا scoped_ptr. وبعد ولكن يمكنك فصل scoped_ptr عندما تكون مستعدا لتسليم الملكية.

كما جيمس مغطاة جيدا، لا يمكنك فصل مؤشر مشترك.

هل تحتاج إلى أصحاب متعددة داخليا، أم أنك تقوم بنقل الملكية من فصلك إلى العميل؟ في هذه الحالة std::auto_ptr قد تناسب الفاتورة.

إذا كنت قلقا بشأن دلالات الدهشة std::auto_ptr, ، يمكنك الاحتفاظ بها داخليا boost::scoped_ptr, وفصله عند نقطة تسليمه - تتركه إلى العميل لحذفه يدويا أو تخزينه يدويا في مؤشر ذكي خاص به.

إذا كان لديك أصحاب متعددة على جانبكم، فيمكنك استخدام عدد تدخلية. داخليا يمكنك بعد ذلك استخدام boost::intrusive__ptr, ، ولكن تسليم المؤشر الخام في الواجهة. يمكن للعميل إما أن يعمل يدويا مع عدد التكاليف، أو تخزينه في boost::intrusive_ptr أنفسهم (لكنك لا تجعلهم يعتمدون عليه)

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