সি ++ ডিসস্ট্রাক্টর কখন ডাকা হয়?


118

বেসিক প্রশ্ন: সি ++ তে কোনও প্রোগ্রাম কখন একটি ক্লাসকে 'ডেস্ট্রাক্টর পদ্ধতিটি কল করে? আমাকে বলা হয়েছে যে যখনই কোনও বস্তু সুযোগের বাইরে চলে যায় বা তার সাথে জড়িত থাকে তখনই এটি ডাকা হয়delete

আরও নির্দিষ্ট প্রশ্ন:

1) যদি পয়েন্টারটির মাধ্যমে অবজেক্টটি তৈরি করা হয় এবং সেই পয়েন্টারটি পরে মুছে ফেলা হয় বা নির্দেশ করতে একটি নতুন ঠিকানা দেওয়া হয়, তবে যে অবজেক্টটি এটি তার ডিস্ট্রাক্টরকে কল করতে নির্দেশ করছে (অন্য কোনও কিছুই এটিকে নির্দেশ করছে না ধরে নিয়ে)?

2) প্রশ্ন 1 এ অনুসরণ করে, যখন কোনও বস্তু সুযোগের বাইরে চলে যায় তখন কোনটি সংজ্ঞায়িত করে (কোন বস্তু প্রদত্ত {ব্লক leaves ছেড়ে যায় সে সম্পর্কে নয়)। সুতরাং, অন্য কথায়, যখন কোনও সংযুক্ত তালিকার কোনও বস্তুর উপরে কোনও ডেস্ট্রাক্টরকে ডাকা হয়?

3) আপনি কি কখনও ম্যানুয়ালি একজন ডেস্ট্রাক্টরকে কল করতে চান?


3
এমনকি আপনার নির্দিষ্ট প্রশ্নগুলিও অনেক বিস্তৃত। "সেই পয়েন্টারটি পরে মুছে ফেলা হয়েছে" এবং "একটি নতুন ঠিকানাতে নির্দেশ দেওয়া" একেবারেই আলাদা। আরও অনুসন্ধান করুন (এর মধ্যে কয়েকটিটির উত্তর দেওয়া হয়েছে) এবং তারপরে যে অংশগুলি আপনি খুঁজে পাননি তার জন্য পৃথক প্রশ্ন জিজ্ঞাসা করুন।
ম্যাথু ফ্ল্যাশেন

উত্তর:


74

1) যদি পয়েন্টারটির মাধ্যমে অবজেক্টটি তৈরি করা হয় এবং সেই পয়েন্টারটি পরে মুছে ফেলা হয় বা নির্দেশ করতে একটি নতুন ঠিকানা দেওয়া হয়, তবে যে অবজেক্টটি এটি তার ডিস্ট্রাক্টরকে কল করতে নির্দেশ করছে (অন্য কোনও কিছুই এটিকে নির্দেশ করছে না ধরে নিয়ে)?

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

2) প্রশ্ন 1 এ অনুসরণ করে, যখন কোনও বস্তু সুযোগের বাইরে চলে যায় তখন কোনটি সংজ্ঞায়িত করে (কোন বস্তু প্রদত্ত {ব্লক leaves ছেড়ে যায় সে সম্পর্কে নয়)। সুতরাং, অন্য কথায়, যখন কোনও সংযুক্ত তালিকার কোনও বস্তুর উপরে কোনও ডেস্ট্রাক্টরকে ডাকা হয়?

এটি লিঙ্কযুক্ত তালিকার বাস্তবায়নের উপর নির্ভর করে। সাধারণ সংগ্রহগুলি যখন তাদের ধ্বংস করা হয় তখন তাদের সমস্ত উপস্থিত বস্তু ধ্বংস করে।

সুতরাং, পয়েন্টারগুলির একটি লিঙ্কযুক্ত তালিকা সাধারণত পয়েন্টারগুলিকে ধ্বংস করবে তবে তারা দেখানো বস্তুগুলিকে নয়। (যা সঠিক হতে পারে They এগুলি অন্যান্য পয়েন্টারগুলির দ্বারা রেফারেন্স হতে পারে)) বিশেষত পয়েন্টারগুলি রাখার জন্য ডিজাইন করা একটি লিঙ্কযুক্ত তালিকা, তবে, এটি তার নিজের ধ্বংসের উপরের জিনিসগুলি মুছে ফেলতে পারে।

স্মার্ট পয়েন্টারগুলির একটি লিঙ্কযুক্ত তালিকা যখন পয়েন্টারগুলি মোছা হয় তখন স্বয়ংক্রিয়ভাবে অবজেক্টগুলি মুছতে পারে বা যদি তাদের কাছে আরও কোনও রেফারেন্স না থাকে তবে তা করতে পারে। আপনি যা চান টুকরোগুলি বেছে নেওয়ার বিষয়টি আপনার পক্ষে নির্ভর করে।

3) আপনি কি কখনও ম্যানুয়ালি একজন ডেস্ট্রাক্টরকে কল করতে চান?

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

// pointer is destroyed because it goes out of scope,
// but not the object it pointed to. memory leak
if (1) {
 Foo *myfoo = new Foo("foo");
}


// pointer is destroyed because it goes out of scope,
// object it points to is deleted. no memory leak
if(1) {
 Foo *myfoo = new Foo("foo");
 delete myfoo;
}

// no memory leak, object goes out of scope
if(1) {
 Foo myfoo("foo");
}

2
আমি ভেবেছিলাম আপনার উদাহরণের শেষটি একটি ফাংশন ঘোষণা করেছে? এটি "সর্বাধিক ভেক্সিং পার্স" এর একটি উদাহরণ। (অন্য আরও তুচ্ছ বিষয় হ'ল আমার ধারণা আপনি new Foo()মূলধন 'এফ' দিয়েছিলেন))
স্টুয়ার্ট গোলোডেটজ

1
আমার মনে Foo myfoo("foo")হয় সর্বাধিক ভেক্সিং পার্স নয়, তবে char * foo = "foo"; Foo myfoo(foo);
কোসিন

এটি একটি বোকা প্রশ্ন হতে পারে, কিন্তু delete myFooআগে বলা উচিত নয় Foo *myFoo = new Foo("foo");? অন্যথায় আপনি সদ্য নির্মিত বস্তু মুছবেন, না?
ম্যাথিউস রোকা

লাইনের myFooআগে নেই Foo *myFoo = new Foo("foo");। এই লাইনটি myFooবিদ্যমান যে কোনওটিকে ছায়াময় বলে ডাকা এক নতুন ভেরিয়েবল তৈরি করে । যদিও এই ক্ষেত্রে, myFooউপরের কোনও উপস্থিতি নেই যেহেতু উপরেরটি ক্ষেত্রের পরিধিতে রয়েছে if, যা শেষ হয়েছে।
ডেভিড শোয়ার্জ

1
@ গ্যালাকিটিকুহ একটি "স্মার্ট পয়েন্টার" এমন একটি জিনিস যা কোনও জিনিসের পয়েন্টারের মতো কাজ করে তবে এর মধ্যে এমন বৈশিষ্ট্যও রয়েছে যা সেই বস্তুর আজীবন পরিচালনা সহজ করে তোলে।
ডেভিড শোয়ার্টজ

20

অন্যরা ইতিমধ্যে অন্যান্য সমস্যাগুলিকে সম্বোধন করেছে, সুতরাং আমি কেবল একটি পয়েন্ট দেখব: আপনি কি কখনও কোনও জিনিস ম্যানুয়ালি মুছতে চান?

উত্তরটি হল হ্যাঁ. @ ডেভিডশওয়ার্টজ একটি উদাহরণ দিয়েছেন তবে এটি মোটামুটি অস্বাভাবিক। আমি একটি উদাহরণ দিচ্ছি যা প্রচুর সি ++ প্রোগ্রামার সর্বদা ব্যবহার করে: এর নীচে রয়েছে: std::vector(এবং std::dequeযদিও এটি যথেষ্ট পরিমাণে ব্যবহৃত হয় না)।

যেমনটি বেশিরভাগ লোকেরা জানেন, std::vectorআপনি যখন তার বর্তমান বরাদ্দটি ধরে রাখতে পারেন তার চেয়ে বেশি আইটেম যুক্ত করলে / মেমরির একটি বৃহত ব্লক বরাদ্দ করবে। এটি যখন এটি করে, তবে এটির মেমরির একটি ব্লক রয়েছে যা বর্তমানে ভেক্টরটির তুলনায় আরও বেশি বস্তু ধারণ করতে সক্ষম ।

এটি পরিচালনা করতে, vectorকভারগুলির নীচে যা করা হয় তা বস্তুর মাধ্যমে কাঁচা মেমরি বরাদ্দ করা হয় Allocator(যা আপনি অন্যথায় নির্দিষ্ট না করে বোঝায় এটি ব্যবহার করে ::operator new)। তারপরে, আপনি যখন push_backকোনও আইটেম যুক্ত করতে (উদাহরণস্বরূপ) ব্যবহার করেন vector, অভ্যন্তরীণভাবে ভেক্টর placement newতার স্মৃতি স্পেসের (পূর্ববর্তী) অব্যবহৃত অংশে একটি আইটেম তৈরি করতে একটি ব্যবহার করে ।

এখন, যখন / আপনি eraseভেক্টর থেকে কোনও আইটেম হন? এটি কেবল ব্যবহার করতে পারে না delete- এটি তার মেমরির পুরো ব্লক প্রকাশ করবে; অন্য কোনও ব্যক্তিকে বিনষ্ট না করে, বা মেমোরির যে কোনও ব্লক এটি নিয়ন্ত্রণ করে না তা ছাড়িয়ে ছাড়ানোর জন্য এটির একটি বস্তু ধ্বংস করতে হবে (উদাহরণস্বরূপ, যদি আপনি eraseকোনও ভেক্টর থেকে 5 টি আইটেম করেন, তবে অবিলম্বে push_backআরও 5 টি আইটেম রয়েছে, এটি গ্যারান্টিযুক্ত যে ভেক্টর পুনরায় কল্পনা করবে না মেমরি আপনি যখন এটি করতে।

এটি করার জন্য, ভেক্টর স্পষ্টভাবে ডেস্ট্রাক্টরকে কল করে মেমরিতে থাকা অবজেক্টগুলিকে সরাসরি ধ্বংস করে, না ব্যবহার করে delete

যদি, অনুধাবন করা হয় তবে অন্য কারও কাছে একটি স্ট্রোক ব্যবহার করে একটি মোটামুটি করণীয়ের মতো স্টোরেজ ব্যবহার করে লিখতে vectorহয় (বা এর কিছু রূপ যেমন std::dequeসত্যিই হয়) আপনি প্রায় একই কৌশলটি ব্যবহার করতে চাইবেন।

উদাহরণস্বরূপ, আসুন বিবেচনা করুন আপনি কীভাবে একটি বিজ্ঞপ্তি রিং-বাফার জন্য কোড লিখতে পারেন।

#ifndef CBUFFER_H_INC
#define CBUFFER_H_INC

template <class T>
class circular_buffer {
    T *data;
    unsigned read_pos;
    unsigned write_pos;
    unsigned in_use;
    const unsigned capacity;
public:
    circular_buffer(unsigned size) :
        data((T *)operator new(size * sizeof(T))),
        read_pos(0),
        write_pos(0),
        in_use(0),
        capacity(size)
    {}

    void push(T const &t) {
        // ensure there's room in buffer:
        if (in_use == capacity) 
            pop();

        // construct copy of object in-place into buffer
        new(&data[write_pos++]) T(t);
        // keep pointer in bounds.
        write_pos %= capacity;
        ++in_use;
    }

    // return oldest object in queue:
    T front() {
        return data[read_pos];
    }

    // remove oldest object from queue:
    void pop() { 
        // destroy the object:
        data[read_pos++].~T();

        // keep pointer in bounds.
        read_pos %= capacity;
        --in_use;
    }
  
~circular_buffer() {
    // first destroy any content
    while (in_use != 0)
        pop();

    // then release the buffer.
    operator delete(data); 
}

};

#endif

মানক ধারকগুলি থেকে ভিন্ন, এটি সরাসরি operator newএবং ব্যবহার করে operator deletedirectly আসল ব্যবহারের জন্য, আপনি সম্ভবত একটি বরাদ্দকারী শ্রেণি ব্যবহার করতে চান, তবে এই মুহুর্তের জন্য এটি অবদানের চেয়ে বিভ্রান্ত করার আরও বেশি কিছু করবে (আইএমও, যাইহোক)।


9
  1. আপনি যখন কোনও বস্তু দিয়ে এটি তৈরি করেন new, আপনি কল করার জন্য দায়বদ্ধ delete। আপনি যখন কোনও অবজেক্ট তৈরি করেন make_shared, ফলাফল shared_ptrগণনা রোধে এবং কল করার ক্ষেত্রে দায়বদ্ধ থাকে deleteযখন ব্যবহারের সংখ্যা শূন্য হয়।
  2. সুযোগের বাইরে যাওয়ার অর্থ একটি ব্লক ছেড়ে যাওয়া। এটি যখন ডাস্ট্রাক্টরকে ডাকা হয় তখন ধরে নেওয়া হয় যে বস্তুটি বরাদ্দ করা হয়নিnew (যেমন এটি স্ট্যাক অবজেক্ট)।
  3. আপনি যখন কোনও বসানো জায়গাnew দিয়ে অবজেক্ট বরাদ্দ করেন কেবল তখনই যখন আপনাকে কোনও ডেস্ট্রাক্টরকে স্পষ্টভাবে কল করতে হয় ।

1
রেফারেন্স গণনা (শেয়ারড_পিটার) রয়েছে, যদিও স্পষ্টতই প্লেইন পয়েন্টারগুলির জন্য নয়।
পাব্বি

1
@ পাব্বি: ভাল কথা, আসুন ভাল অনুশীলনের প্রচার করি। সম্পাদিত উত্তর।
এমসাল্টারস

6

1) অবজেক্টগুলি 'পয়েন্টারগুলির মাধ্যমে' তৈরি করা হয় না। এখানে একটি পয়েন্টার রয়েছে যা আপনাকে 'নতুন' বলে নির্ধারিত হয় is এই আপনি বোঝাতে চাইছেন তা ধরে নিচ্ছেন, আপনি যদি পয়েন্টারে 'মুছুন' কল করেন তবে এটি বস্তুটিকে পয়েন্টার ডিरेফারেন্সগুলি মুছে ফেলবে (এবং ধ্বংসকারীকে কল করবে)। আপনি যদি পয়েন্টারটিকে অন্য কোনও অবজেক্টে অর্পণ করেন তবে একটি মেমরি ফাঁস হবে; সি ++ এর কিছুই আপনার জন্য আবর্জনা সংগ্রহ করবে না।

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

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


3

3 প্রশ্নের বিশদ উত্তর দিতে: হ্যাঁ, এমন কিছু ঘটনা (বিরল) আছে যখন আপনি ডাস্টব্লিংক্লাইটলাইট পর্যবেক্ষণ করেছেন, বিশেষত যখন আপনি ডেস্ট্রাক্টরকে স্পষ্টভাবে কল করতে পারেন, বিশেষত একটি প্লাসমেন্টের নতুন অংশের অংশ হিসাবে।

এর একটি দৃ concrete় উদাহরণ দিতে:

#include <iostream>
#include <new>

struct Foo
{
    Foo(int i_) : i(i_) {}
    int i;
};

int main()
{
    // Allocate a chunk of memory large enough to hold 5 Foo objects.
    int n = 5;
    char *chunk = static_cast<char*>(::operator new(sizeof(Foo) * n));

    // Use placement new to construct Foo instances at the right places in the chunk.
    for(int i=0; i<n; ++i)
    {
        new (chunk + i*sizeof(Foo)) Foo(i);
    }

    // Output the contents of each Foo instance and use an explicit destructor call to destroy it.
    for(int i=0; i<n; ++i)
    {
        Foo *foo = reinterpret_cast<Foo*>(chunk + i*sizeof(Foo));
        std::cout << foo->i << '\n';
        foo->~Foo();
    }

    // Deallocate the original chunk of memory.
    ::operator delete(chunk);

    return 0;
}

এই ধরণের জিনিসটির উদ্দেশ্য হ'ল অবজেক্ট কনস্ট্রাকশন থেকে মেমরির বরাদ্দকে দ্বিগুণ করা।


2
  1. পয়েন্টার - নিয়মিত পয়েন্টারগুলি RAII সমর্থন করে না। স্পষ্ট deleteনা হলে আবর্জনা থাকবে be ভাগ্যক্রমে সি ++ এর অটো পয়েন্টার রয়েছে যা এটি আপনার জন্য পরিচালনা করে!

  2. সুযোগ - কোনও ভেরিয়েবল আপনার প্রোগ্রামে কখন অদৃশ্য হয়ে যায় তা ভেবে দেখুন । সাধারণত এটি আপনার শেষের দিকে রয়েছে {block}

  3. ম্যানুয়াল ধ্বংস - এটি কখনও চেষ্টা করবেন না। আপনার জন্য কেবল সুযোগ এবং RAII যাদু করার সুযোগ দিন।


একটি নোট: আপনার লিঙ্কটি যেমন উল্লেখ করেছে ততক্ষণ অটো_পিটার অবচিত হয়।
tnecniv

std::auto_ptrহ্যাঁ, সি ++ 11 এ অবমূল্যায়ন করা হয়েছে। যদি ওপিতে আসলে সি ++ 11 থাকে তবে তার std::unique_ptrএকক মালিকদের জন্য, বা std::shared_ptrরেফারেন্স-গণনা করা একাধিক মালিকদের জন্য ব্যবহার করা উচিত ।
খ্রিস্টিয়াকক

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

@ মার্টিনজেমস আপনি কি এমন একটি কম্পিউটার কলের উদাহরণ পোস্ট করতে পারেন যা সংকলক বুঝতে পারে না? এবং আপনি কীভাবে সারিটি প্রয়োগ করছেন? না std::queue<std::shared_ptr>?আমি দেখেছি যে, pipe()একটি প্রযোজক এবং ভোক্তা থ্রেড করতে সম্পাতবিন্দু অনেক সহজ, যদি কপি অত্যন্ত ব্যয়বহুল নয় মধ্যে।
খ্রিস্টিয়াকক

মায়োবজেক্ট = নতুন মাইক্লাস (); PostMessage (aHandle, WM_APP, 0, LPPARAM (myObject));
মার্টিন জেমস

1

আপনি যখনই "নতুন" ব্যবহার করেন, অর্থাত্ কোনও পয়েন্টারের সাথে একটি ঠিকানা সংযুক্ত করুন, বা বলতে গেলে আপনি গাদা জায়গার দাবি করেন, আপনাকে এটি "মুছুন" দরকার।
1. চোখ, আপনি যখন কোনও কিছু মুছবেন তখন ধ্বংসকারীকে ডাকা হবে।
২. যখন লিঙ্কযুক্ত তালিকার ডেস্ট্রাক্টর বলা হয় তখন তাকে অবজেক্টের ডেস্ট্রাক্টর বলা হয়। তবে সেগুলি যদি পয়েন্টার হয় তবে আপনাকে সেগুলি ম্যানুয়ালি মুছে ফেলতে হবে। 3. যখন স্থানটি "নতুন" দ্বারা দাবি করা হয়


0

হ্যাঁ, যখন কোনও বস্তু স্ট্যাকের উপরে থাকে বা আপনি যখন deleteকোনও বস্তুর দিকে পয়েন্টারে কল করেন তখন কোনও ডেস্ট্রাক্টর (ওরফে ডটার) ডাকা হয় ।

  1. যদি পয়েন্টারটির মাধ্যমে মুছে ফেলা হয় deleteতবে ডটরটি কল করা হবে। আপনি যদি deleteপ্রথমে কল না করে পয়েন্টারটিকে পুনরায় স্বাক্ষর করেন তবে আপনি একটি মেমরি ফাঁস পাবেন কারণ কোনও কোনও স্থানে স্মৃতিতে এখনও অবজেক্টটি বিদ্যমান। পরবর্তী উদাহরণে, ডাক্তারকে ডাকা হয় না।

  2. তালিকাটি নষ্ট হওয়ার সাথে সাথে একটি ভাল লিঙ্কযুক্ত তালিকার প্রয়োগটি তালিকার সমস্ত অবজেক্টের ডটরকে কল করবে (কারণ আপনি কোনও পদ্ধতিটিকে গন্তব্য হিসাবে ডেকেছেন বা এটি নিজেই সুযোগের বাইরে চলে গেছে)। এটি বাস্তবায়ন নির্ভর।

  3. আমি এটি সন্দেহ করি, তবে সেখানে কিছু বিজোড় পরিস্থিতি থাকলে আমি অবাক হব না।


1
"আপনি যদি প্রথমে মুছুন কল না করে পয়েন্টারটি পুনরায় স্বাক্ষর করেন তবে আপনি একটি স্মৃতি ফাঁস পাবেন কারণ বস্তুটি কোথাও কোথাও স্মৃতিতে বিদ্যমান" " অগত্যা। এটি অন্য পয়েন্টারের মাধ্যমে মুছে ফেলা হতে পারে।
ম্যাথিউ ফ্ল্যাশেন

0

যদি বস্তুটি কোনও পয়েন্টারের মাধ্যমে না তৈরি করা হয় (উদাহরণস্বরূপ, এ এ 1 = এ ();), অবজেক্টর ডেকে আনা হয় যখন বস্তুটি ধ্বংস করা হয়, সর্বদা যখন বস্তুটি পড়ে থাকে সেখানে কাজ শেষ হয় example উদাহরণস্বরূপ:

void func()
{
...
A a1 = A();
...
}//finish


কোডটি "সমাপ্তি" -এ লাইন করার জন্য যখন ডেস্ট্রাক্টরকে ডাকা হয়।

যদি পয়েন্টারটির মাধ্যমে অবজেক্টটি তৈরি করা হয় (উদাহরণস্বরূপ, এ * a2 = নতুন এ ();), পয়েন্টারটি মুছে ফেলা হয় তখন ডেস্ট্রাক্টর ডেকে আনা হয় (a2 মুছুন;) মুছে ফেলার আগে নতুন ঠিকানা, মেমরি ফাঁস ঘটে। এটি একটি বাগ।

একটি লিঙ্কযুক্ত তালিকায়, আমরা যদি std :: list <> ব্যবহার করি, তবে আমাদের ডেস্ট্রাক্টর বা মেমরি ফাঁস সম্পর্কে কোনও চিন্তা করার দরকার নেই কারণ std :: list <> আমাদের জন্য এগুলি সব শেষ করেছে। আমাদের লিখিত লিঙ্কে, আমাদের বিবরণী লিখতে হবে এবং স্পষ্ট করে পয়েন্টারটি মুছে ফেলা উচিত ther অন্যদিকে, এটি মেমরি ফাঁস হওয়ার কারণ হবে।

আমরা খুব কমই ম্যানুয়ালি একজন ডেস্ট্রাক্টরকে ডাকি। এটি সিস্টেমের জন্য সরবরাহকারী একটি ফাংশন।

আমার দূর্বল ইংরেজির জন্য দুঃখিত!


এটি সত্য নয় যে আপনি ম্যানুয়ালি কোনও ডেস্ট্রাক্টরকে কল করতে পারবেন না - আপনি পারেন (উদাহরণস্বরূপ আমার উত্তরে কোডটি দেখুন)। সত্য কথাটি হ'ল যে
সময়টির

0

মনে রাখবেন যে কোনও অবজেক্টের কনস্ট্রাক্টরকে সেই বস্তুর জন্য মেমরি বরাদ্দ হওয়ার সাথে সাথে ডাকা হয় এবং যেখানে object অবজেক্টের স্মৃতিটিকে ক্ষুণ্ন করার আগে ডেস্ট্রাক্টর বলা হয়।

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