سؤال

ما فائدة وجود المدمر كخاص؟

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

المحلول

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

على سبيل المثال، إذا كنت تقوم بنوع من أنواع عد المراجع، فيمكنك جعل الكائن (أو المدير الذي تم تعيينه "صديقًا") مسؤولاً عن حساب عدد المراجع لنفسه وحذفها عندما يصل الرقم إلى الصفر.من شأن الطبيب الخاص أن يمنع أي شخص آخر من حذفه عندما لا تزال هناك إشارات إليه.

في مثال آخر، ماذا لو كان لديك كائن له مدير (أو هو نفسه) قد يدمره أو قد يرفض تدميره اعتمادًا على شروط أخرى في البرنامج، مثل أن يكون اتصال قاعدة البيانات مفتوحًا أو أن يكون الملف قيد الكتابة.يمكن أن يكون لديك طريقة "request_delete" في الفصل الدراسي أو المدير الذي سيتحقق من هذا الشرط وسيقوم إما بحذفه أو رفضه، وإرجاع حالة تخبرك بما فعلته.وهذا أكثر مرونة بكثير من مجرد استدعاء "حذف".

نصائح أخرى

لا يمكن أبدا أن يتم إنشاء مثل هذا الكائن على المكدس. دائما على الكومة. وحذف ما ينبغي القيام به عن طريق صديق أو أحد أفراد. وقال المنتج قد تستخدم التسلسل الهرمي كائن واحد والعرف الذاكرة مدير - مثل هذه السيناريوهات قد تستخدم dtor الخاص

#include <iostream>
class a {
    ~a() {}
    friend void delete_a(a* p);
};


void delete_a(a* p)  {
    delete p;
}

int main()
{
    a *p = new a;
    delete_a(p);

    return 0;
}

وعندما لا تريد للمستخدمين للوصول إلى المدمر، أي تريد الكائن ليتم تدميرها إلا من خلال وسائل أخرى.

http://blogs.msdn.com/larryosterman/ أرشيف / 2005/07/01 / 434684.aspx يعطي مثالا على ذلك، حيث الكائن هو إشارة عدها، وينبغي أن دمرت فقط من الكائن نفسه عندما يذهب العد من الصفر.

وCOM يستخدم هذه الاستراتيجية لحذف المثيل. COM يجعل المدمر الخاص ويوفر واجهة لحذف المثيل.

وهنا مثال على ما يمكن أن تبدو طريقة الإصدار مثل.

int MyRefCountedObject::Release() 
{
 _refCount--;
 if ( 0 == _refCount ) 
 {
    delete this;
    return 0;
 }
 return _refCount;
}

وكائنات ATL COM هي مثال ساطع على هذا النمط.

وإضافة إلى إجابات موجودة بالفعل هنا. منشئات خاصة و destructors مفيدة جدا حين تنفيذ مصنع حيث تم إنشاؤها مطلوبة الكائنات التي سيتم تخصيصها على الكومة. أن، بشكل عام، أن تنشأ الكائنات / حذف من قبل عضو ثابت أو صديق. مثال على الاستخدام النموذجي:

class myclass
{
public:
    static myclass* create(/* args */)  // Factory
    {
        return new myclass(/* args */);
    }

    static void destroy(myclass* ptr)
    {
        delete ptr;
    }
private:
    myclass(/* args */) { ... }         // Private CTOR and DTOR
    ~myclass() { ... }                  // 
}

int main ()
{
    myclass m;                          // error: ctor and dtor are private
    myclass* mp = new myclass (..);     // error: private ctor
    myclass* mp = myclass::create(..);  // OK
    delete mp;                          // error: private dtor
    myclass::destroy(mp);               // OK
}

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

وأنا أعلم أنك لم يسأل عن المدمر الخاص. هنا هو كيف يمكنني استخدام تلك المحمية. الفكرة هي أنك لا تريد حذف الطبقة الرئيسية من خلال المؤشر إلى الدرجة التي تضيف وظائف اضافية لالرئيسي.
في المثال أدناه لا أريد GuiWindow المراد حذفه من خلال مؤشر HandlerHolder.

class Handler
{
public:
    virtual void onClose() = 0;
protected:
    virtual ~Handler();
};

class HandlerHolder
{
public:
    void setHandler( Handler* );
    Handler* getHandler() const;
protected:
    ~HandlerHolder(){}
private:
    Handler* handler_;
};

class GuiWindow : public HandlerHolder
{
public:
    void finish()
    {
        getHandler()->onClose();
    }

    virtual ~GuiWindow(){}
};

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

#include <iostream>

class PrivateCD
{
private:
    PrivateCD(int i) : _i(i) {};
    ~PrivateCD(){};
    int _i;
public:
    static void TryMe(int i)
    {
        PrivateCD p(i);
        cout << "inside PrivateCD::TryMe, p._i = " << p._i << endl;
    };
};

int main()
{
    PrivateCD::TryMe(8);
};

وهذا الرمز سوف تنتج الإخراج: داخل PrivateCD :: TryMe، p._i = 8

قد يكون وسيلة للتعامل مع هذه المشكلة في نظام التشغيل Windows حيث يمكن لكل وحدة استخدام كومة مختلفة، مثل في تصحيح الكومة. إذا لم يتم التعامل مع هذه المشكلة بشكل صحيح سيئة < وأ href = "https://stackoverflow.com/questions/443147/c-mix-new-delete-between-libs"> أشياء يمكن أن يحدث.

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