ডেস্ট্রাক্টরকে বেসরকারী হিসাবে ব্যবহার করার কী আছে?


194

ডেস্ট্রাক্টরকে বেসরকারী হিসাবে ব্যবহার করার কী আছে?

উত্তর:


176

মূলত, যে কোনও সময় আপনি চাইলে অন্য কোনও শ্রেণি আপনার শ্রেণীর অবজেক্টের জীবনচক্রের জন্য দায়বদ্ধ হোক, বা কোনও জিনিসের ধ্বংস রোধ করার কারণ আপনার কাছে রয়েছে, আপনি ধ্বংসকারীকে ব্যক্তিগত করতে পারেন।

উদাহরণস্বরূপ, যদি আপনি কোনও প্রকার রেফারেন্স গণনা করার জিনিসটি করেন তবে আপনার কাছে রেফারেন্সের সংখ্যা গণনা করার জন্য অবজেক্টটি (বা পরিচালক "বন্ধু" এড) থাকতে পারে এবং সংখ্যাটি শূন্য হিট হওয়ার পরে এটি মুছতে পারে। কোনও প্রাইভেট ডর্টর অন্য কারও কাছে এটি মুছে ফেলা থেকে বিরত রাখতে পারে যখন তার এখনও উল্লেখ রয়েছে।

অন্য উদাহরণস্বরূপ, আপনার যদি এমন কোনও অবজেক্ট থাকে যার ম্যানেজার থাকে (বা নিজেই) এটি ধ্বংস করতে পারে বা প্রোগ্রামের অন্যান্য শর্তগুলির উপর নির্ভর করে এটি ধ্বংস করতে অস্বীকার করতে পারে, যেমন একটি ডাটাবেস সংযোগ খোলা রয়েছে বা কোনও ফাইল লিখিত হচ্ছে। আপনার ক্লাসে বা পরিচালককে "অনুরোধ_ডিলিট" পদ্ধতি থাকতে পারে যা সেই শর্তটি পরীক্ষা করবে এবং এটি হয় মুছে ফেলবে বা প্রত্যাখ্যান করবে এবং এটি কী করেছে তা আপনাকে জানাতে একটি স্থিতি ফিরিয়ে দেবে। এটি আরও নমনীয় যে কেবল "মুছুন" কল করে।


73

এই জাতীয় বস্তু স্ট্যাকের উপরে তৈরি করা যায় না। সর্বদা গাদা। এবং মুছে ফেলতে হবে বন্ধু বা কোনও সদস্যের মাধ্যমে। কোনও পণ্য একটি একক অবজেক্ট শ্রেণিবিন্যাস এবং একটি কাস্টম মেমরি-পরিচালক ব্যবহার করতে পারে - এই জাতীয় পরিস্থিতিগুলি কোনও প্রাইভেট ডর্টর ব্যবহার করতে পারে।

#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;
}

19
সংশোধন: এই জাতীয় বস্তু স্ট্যাকের উপর তৈরি করা যেতে পারে (তবে কেবলমাত্র একটি বন্ধু বা তার নিজের ক্ষেত্রেই)।
টমাস এডিং

অতিরিক্তভাবে এটি কোনও স্থিতিশীল বা বৈশ্বিক অবজেক্টকে (যেমন, "স্ট্যাটিক স্টোরেজ সময়কাল" থাকতে পারে) কোনও হোস্টেড বাস্তবায়নে (কারণ ডেস্ট্রাক্টর প্রোগ্রাম প্রস্থান করার সময় ডেকে আনা হবে) বাড়াতে পারে না।
পিটার - মনিকা পুনরায় ইনস্টল করুন

45

আপনি যখন ব্যবহারকারীদের নাশককে অ্যাক্সেস করতে চান না, অর্থাত্‍ আপনি চাইছেন যে কেবলমাত্র অন্য উপায়ে অবজেক্টটি ধ্বংস হয়ে যাবে।

http://blogs.msdn.com/larryosterman/archive/2005/07/01/434684.aspx একটি উদাহরণ দেয়, যেখানে বস্তুটি রেফারেন্স গণনা করা হয় এবং কেবল যখন বস্তুটি শূন্যের দিকে চলে যায় কেবল তখনই এটি বস্তু দ্বারা ধ্বংস করা উচিত।


17

সিওএম উদাহরণটি মোছার জন্য এই কৌশলটি ব্যবহার করে। সিওএম ধ্বংসকারীকে ব্যক্তিগত করে তোলে এবং উদাহরণটি মোছার জন্য একটি ইন্টারফেস সরবরাহ করে।

এখানে একটি রিলিজ পদ্ধতি কেমন হবে তার একটি উদাহরণ is

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

এটিএল সিওএম অবজেক্টস এই প্যাটার্নের একটি প্রধান উদাহরণ।


8

ইতিমধ্যে এখানে উপস্থিত উত্তর যোগ করা; প্রাইভেট কনস্ট্রাক্টর এবং ডেস্ট্রাক্টরগুলি এমন কারখানাটি কার্যকর করার সময় বেশ কার্যকর হয় যেখানে তৈরি বস্তুগুলি গাদাতে বরাদ্দ করা প্রয়োজন। বস্তুগুলি, সাধারণভাবে, স্থির সদস্য বা বন্ধু দ্বারা তৈরি করা / মুছে ফেলা হত। একটি সাধারণ ব্যবহারের উদাহরণ:

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
}

7

ক্লাসটি কেবল নিজেই মুছতে পারে। আপনি যদি রেফারেন্স গণনা করা অবজেক্টের কিছু চেষ্টা তৈরি করে থাকেন তবে দরকারী। তারপরে কেবল প্রকাশের পদ্ধতিটিই ত্রুটি এড়াতে সম্ভবত আপনাকে সহায়তা করতে পারে object


3

আমি জানি আপনি বেসরকারী ধ্বংসকারী সম্পর্কে জিজ্ঞাসা করেছিলেন। এখানে আমি সুরক্ষিতগুলি কীভাবে ব্যবহার করি। ধারণাটি হ'ল আপনি পয়েন্টারের মাধ্যমে মূল শ্রেণীর মুছতে চান না যা মূলটিতে অতিরিক্ত কার্যকারিতা যুক্ত করে।
নীচের উদাহরণে আমি চাই না যে কোনও হ্যান্ডলারহোল্ডার পয়েন্টারের মাধ্যমে গুই উইন্ডো মোছা হোক।

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(){}
};

3

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);
};

এই কোডটি আউটপুট উত্পাদন করবে: প্রাইভেটসিডি এর :: :: ট্রাইমি, পি_আই = 8


3
আমি দৃ sure়ভাবে নিশ্চিত যে সংক্ষেপে বোঝানো হয়েছে যে কোডটি যা আপনার ক্লাস ব্যবহার করে তা স্ট্যাকের উপরের ক্লাসটি ইনস্ট্যান্ট করতে পারে না। অবশ্যই আপনি ক্লাসের পদ্ধতিগুলির মধ্যে স্ট্যাকের উপর ক্লাসটি এখনও ইনস্ট্যান্ট করতে পারেন , যেহেতু সেই প্রসঙ্গে আপনি ব্যক্তিগত মেম্বারগুলি অ্যাক্সেস করতে পারেন।
এডওয়ার্ড লোপার

2

এটি উইন্ডোজের সমস্যা মোকাবেলার এমন এক উপায় হতে পারে যেখানে প্রতিটি মডিউল পৃথক হিপ যেমন ডিবাগ হিপ ব্যবহার করতে পারে । যদি সমস্যাটি সঠিকভাবে পরিচালিত না হয় তবে খারাপ জিনিসগুলি ঘটতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.