এটি মুছে ফেলা অনুমোদিত?


232

delete this;ক্লাসের সেই উদাহরণে ডিলিট-স্টেটমেন্টটি শেষ বিবৃতি যা কার্যকর করা হবে তা অনুমোদিত ? অবশ্যই আমি নিশ্চিত যে - thisপয়েন্টার দ্বারা উপস্থাপিত বস্তুটি লায় new-তৈরি created

আমি এই জাতীয় কিছু সম্পর্কে চিন্তা করছি:

void SomeModule::doStuff()
{
    // in the controller, "this" object of SomeModule is the "current module"
    // now, if I want to switch over to a new Module, eg:

    controller->setWorkingModule(new OtherModule());

    // since the new "OtherModule" object will take the lead, 
    // I want to get rid of this "SomeModule" object:

    delete this;
}

আমি কি ইহা করতে পারি?


13
মূল সমস্যাটি হ'ল আপনি delete thisযদি শ্রেণীর অবজেক্ট তৈরির জন্য ক্লাস এবং বরাদ্দ পদ্ধতির মধ্যে একটি শক্ত সংযোগ তৈরি করেন। এটি অত্যন্ত ওও নকশা, কারণ ওওপি-র সবচেয়ে মৌলিক বিষয় হ'ল স্বায়ত্তশাসিত শ্রেণি তৈরি করা যা তাদের কলকারী কী করছে তা জানে না বা যত্ন করে না। সুতরাং একটি সঠিকভাবে ডিজাইন করা শ্রেণীর এটি কীভাবে বরাদ্দ দেওয়া হয়েছিল তা সম্পর্কে জানা বা যত্ন নেওয়া উচিত নয়। আপনার যদি কোনও কারণে যদি এই জাতীয় উদ্ভাবনী ব্যবস্থার প্রয়োজন হয় তবে আমি মনে করি যে আরও ভাল নকশা হ'ল আসল শ্রেণীর চারপাশে একটি র‌্যাপার ক্লাস ব্যবহার করা এবং র‌্যাপারটি বরাদ্দের সাথে চুক্তি করা উচিত।
লন্ডিন

আপনি কি মুছে ফেলতে পারবেন না setWorkingModule?
জিমি টি।

উত্তর:


238

বিশেষত এর জন্য সি ++ এফএকিউ লাইটের একটি এন্ট্রি রয়েছে

আমি মনে করি এই উদ্ধৃতিটি এটি সুন্দরভাবে উপস্থাপন করেছে

যতক্ষণ আপনি যত্নবান হন, কোনও বস্তুর আত্মহত্যা করা ঠিক হবে (এটি মুছুন)।


15
সংশ্লিষ্ট এফকিউএরও কিছু দরকারী মন্তব্য রয়েছে: yosefk.com/c++fqa/heap.html#fqa-16.15
আলেকজান্দ্রি সি

1
সুরক্ষার জন্য আপনি এটি স্ট্যাকের উপর বা অ্যারে বা ভেক্টরের অংশ হিসাবে তৈরি না করে তা নিশ্চিত করতে মূল অবজেক্টে ব্যক্তিগত ডেস্ট্রাক্টর ব্যবহার করতে পারেন।
সেম কল্যাঙ্কু

'সাবধান' হিসাবে সংজ্ঞা দিন
CinCout

3
'যত্নশীল' সংযুক্ত FAQ নিবন্ধে সংজ্ঞায়িত করা হয়। (যদিও এফকিউএ লিঙ্কটি বেশিরভাগ ক্ষেত্রেই দেয় - এতে প্রায় প্রতিটি কিছুর মতো - C ++ কত খারাপ)
CharonX

88

হ্যাঁ, delete this;ফলাফলগুলি সংজ্ঞায়িত করা হয়েছে, যতক্ষণ না (যতক্ষণ আপনি উল্লেখ করেছেন) আপনি নিশ্চিত করেছেন যে বস্তুটি গতিশীলভাবে বরাদ্দ দেওয়া হয়েছিল, এবং (অবশ্যই) কখনই বস্তুটি ধ্বংস হওয়ার পরে ব্যবহার করার চেষ্টা করবেন না। বছরের পর বছরগুলিতে, স্ট্যান্ডার্ডটি বিশেষভাবে delete this;অন্য কিছু পয়েন্টার মোছার বিপরীতে কী বলে সে সম্পর্কে অনেক প্রশ্ন জিজ্ঞাসা করা হয়েছে । এর উত্তর মোটামুটি সংক্ষিপ্ত এবং সহজ: এটি কিছুই বলে না। এটি কেবল বলেছে যে deleteএর অপারেন্ড অবশ্যই একটি অভিব্যক্তি যা কোনও পয়েন্টারকে পয়েন্টার বা বস্তুর একটি অ্যারে নির্দিষ্ট করে দেয়। এটি মেমরিটি প্রকাশের জন্য কল (কী (যদি কোনও)) deleteডিলোকেশন ফাংশনটি কীভাবে চিত্রিত করে তা যেমন কিছুটা বিশদে চলে যায় তবে (§ [expr.delete]) এর পুরো বিভাগটি delete this;নির্দিষ্টভাবে উল্লেখ করে না । ধ্বংসকারীদের উপর বিভাগটি উল্লেখ করেdelete this এক জায়গায় (class [class.dtor] / 13):

ভার্চুয়াল ডেস্ট্রাক্টরের সংজ্ঞার বিন্দুতে (একটি অন্তর্নিহিত সংজ্ঞা (15.8) সহ) অ-অ্যারে ডিএলোকেশন ফাংশনটি নির্ধারিত হয় যেন অভিব্যক্তিটির জন্য এটি ডিস্ট্রাক্টরের শ্রেণীর অ-ভার্চুয়াল ডেস্ট্রাক্টরে উপস্থিত হয় (দেখুন 8.3.5 )।

এটি সেই ধারণাটিকে সমর্থন করে যা মানকটিকে delete this;বৈধ বলে মনে করে - যদি এটি অবৈধ হয় তবে এর ধরণটি অর্থবহ হবে না। delete this;আমি জানি যতদূর স্ট্যান্ডার্ড উল্লেখযোগ্য একমাত্র জায়গা only

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

আপনি এই কৌশলটি ব্যবহার করার প্রাথমিক সময়টি এমন কোনও বস্তুর সাথে থাকে যা একটি জীবন যা সম্পূর্ণরূপে নিজস্ব its জেমস কানজে যে উদাহরণটি দিয়েছিলেন তার একটি বিলিং / ট্র্যাকিং সিস্টেম যা তিনি একটি ফোন সংস্থার জন্য কাজ করেছিলেন। আপনার কাছে যখন কোনও ফোন কল করা শুরু করা হয়, তখন কিছু এটি নোট করে এবং একটি phone_callঅবজেক্ট তৈরি করে । সেই দিক থেকে, phone_callঅবজেক্টটি ফোন কলটির বিশদ পরিচালনা করে (আপনি ডায়াল করার সময় সংযোগ তৈরি করে, কলটি কখন শুরু হয়েছিল তা বলার জন্য ডাটাবেসে একটি এন্ট্রি যুক্ত করে, সম্ভবত আপনি যদি কোনও সম্মেলন কল করেন তবে আরও বেশি লোককে সংযুক্ত করুন ইত্যাদি) কখন When কলটিতে সর্বশেষ লোকেরা স্তব্ধ হয়ে যায়, phone_callবস্তুটি তার চূড়ান্ত বুক-কিপিং করে (উদাহরণস্বরূপ, আপনি যখন হ্যাঙ্গআপ করেছিলেন তখন ডাটাবেসে একটি এন্ট্রি যুক্ত করে, যাতে তারা আপনার কল কত দিন ছিল তা গণনা করতে পারে) এবং তারপরে নিজেই ধ্বংস হয়ে যায়। জীবনকালphone_callপ্রথম ব্যক্তি কলটি কখন শুরু করে এবং শেষের লোকেরা কলটি ছেড়ে দেয় - তার উপর ভিত্তি করে অবজেক্টটি নির্ভর করা হয় - সিস্টেমের বাকি অংশের দৃষ্টিভঙ্গি থেকে, এটি মূলত সম্পূর্ণ স্বেচ্ছাচারী, সুতরাং আপনি এটিকে কোডের কোনও লিক্সিকাল স্কোপে বেঁধে রাখতে পারবেন না , বা এই আদেশে কিছু।

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


2
ধন্যবাদ, আমি এটি আমার স্মৃতিতে কোথাও রেখে দেব। আমি মনে করি আপনি কনস্ট্রাক্টর এবং ডেস্ট্রাক্টরকে ব্যক্তিগত হিসাবে সংজ্ঞায়িত করেছেন এবং এই জাতীয় অবজেক্ট তৈরি করতে কিছু স্থির কারখানার পদ্ধতি ব্যবহার করেন।
আলেকজান্দ্রি সি

@ আলেকজান্দ্রে: আপনি সম্ভবত বেশিরভাগ ক্ষেত্রেই তা করতে পেরেছিলেন - তিনি যে সিস্টেমটিতে কাজ করছেন তার সমস্ত বিবরণের কাছাকাছি আমি কোথাও জানি না, তবে আমি এ সম্পর্কে নিশ্চিতভাবে বলতে পারি না।
জেরি কফিন

মেমরিটি কীভাবে বরাদ্দ করা হয়েছিল সেই সমস্যাটি প্রায়শই আমি প্রায়শই পেতে পারি bool selfDeleteকনস্ট্রাক্টরে একটি প্যারামিটার অন্তর্ভুক্ত করা যা কোনও সদস্যের ভেরিয়েবলকে বরাদ্দ দেওয়া হয়। মঞ্জুরিপ্রাপ্ত, এর অর্থ প্রোগ্রামারকে এটিতে খুব সহজেই একটি দড়ি বেঁধে দেওয়ার জন্য দড়ি দেওয়া, তবে আমি মনে করি এটি মেমরি ফাঁসের চেয়ে ভাল।
এমব্রেডলি

1
@ এমব্রেডলি: আমিও তাই করেছি, তবে আমার কাছে ক্লদজের মতো যা মনে হচ্ছে তা এড়ানো পছন্দ করেন।
জেরি কফিন

যে কারও যত্ন নিতে পারে ... একটি দুর্দান্ত সুযোগ রয়েছে যে এটি হ্যান্ডেল করা হচ্ছে (কমপক্ষে কিছু অংশে) কোড অনুসারে হুবহু করে this। হ্যাঁ, কোডটি হুবহু পরিচালনা করা হচ্ছে this। ;)
গ্যালাক্সি

46

এটি যদি আপনাকে ভয় দেখায় তবে একটি সঠিক আইনী হ্যাক রয়েছে:

void myclass::delete_me()
{
    std::unique_ptr<myclass> bye_bye(this);
}

আমি মনে করি delete thisআইডেম্যাটিক সি ++ যদিও, এবং আমি এটি কেবল কৌতূহল হিসাবে উপস্থাপন করি।

এমন একটি কেস রয়েছে যেখানে এই কনস্ট্রাক্টটি আসলে কার্যকর - আপনি কোনও ব্যতিক্রম ছুঁড়ে দেওয়ার পরে অবজেক্টটি মুছতে পারেন যার জন্য অবজেক্ট থেকে সদস্যের ডেটা প্রয়োজন। নিক্ষেপ হওয়ার পরে অবধি অবধি বৈধ থাকবে।

void myclass::throw_error()
{
    std::unique_ptr<myclass> bye_bye(this);
    throw std::runtime_exception(this->error_msg);
}

দ্রষ্টব্য: আপনি যদি C ++ 11 এর চেয়েও পুরনো একটি সংকলক ব্যবহার করছেন তবে আপনি এর std::auto_ptrপরিবর্তে ব্যবহার করতে পারেন std::unique_ptr, এটি একই কাজ করবে।


আমি এটি সি ++ 11 ব্যবহার করে সংকলন করতে পারি না, এর জন্য কিছু বিশেষ সংকলক বিকল্প রয়েছে কি? এছাড়াও এটির জন্য এই পয়েন্টারটি সরানোর প্রয়োজন হয় না?
আউল

@ আপনি কী বোঝাতে চেয়েছেন তা নিশ্চিত নয়, এটি আমার পক্ষে কাজ করে: ideone.com/aavQUKঅন্যunique_ptr থেকে একটি তৈরি করার জন্য একটি পদক্ষেপ প্রয়োজন, তবে কোনও কাঁচা পয়েন্টার থেকে নয়। সি ++ 17 এ জিনিসগুলি পরিবর্তিত না হলে? unique_ptr
মার্ক

আহ আহ ++, এটাই হবে। আমার ডি বাক্সে আমার সি ++ আপডেট করতে হবে। আমি আজ রাতে আবার চেষ্টা করব আমার সাম্প্রতিক উত্সাহিত ভেন্টু সিস্টেমে!
আউল

25

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

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


7
+1 টি। আমি বুঝতে পারি না কেন আপনি নিম্নচাপে ছিলেন। "সি ++ লিখতে হবে যাতে ক্লাসটি গাদা, একটি অ্যারে বা স্ট্যাকের উপর ইনস্ট্যান্ট করা হয় কিনা" এটি খুব ভাল পরামর্শ।
জো

1
আপনি কেবলমাত্র নির্দিষ্ট একটি ক্লাসে নিজেকে মুছতে চান এমন বস্তুটি গুটিয়ে রাখতে পারেন যা বস্তুটি এবং তারপরে নিজেই মুছে ফেলবে এবং স্ট্যাক বরাদ্দ রোধ করতে এই কৌশলটি ব্যবহার করুন: স্ট্যাকওভারফ্লো / সেকশনস / 124880/… এমন সময় আছে যখন সত্যিই একটি নেই টেকসই বিকল্প. আমি এই কৌশলটি কেবল কোনও থ্রেডকে ডিএলএল ফাংশন দ্বারা স্ব-মুছে ফেলার জন্য ব্যবহার করেছি, তবে থ্রেডটি শেষ হওয়ার আগে অবশ্যই ডিএলএল ফাংশনটি ফিরে আসতে হবে।
ফেলিক্স ডমবাক

আপনি এমনভাবে প্রোগ্রাম করতে পারবেন না যে কেউ আপনার কোডটি দিয়ে কেবল অনুলিপি এবং পেস্ট করছে সেভাবেই এর অপব্যবহার শেষ করে
জিমি টি।

22

এটি অনুমোদিত (কেবলমাত্র তার পরে অবজেক্টটি ব্যবহার করবেন না) তবে আমি অনুশীলনে এই জাতীয় কোড লিখব না। আমি মনে করি যে delete thisযে বলা শুধুমাত্র ফাংশন প্রদর্শিত হওয়া উচিত releaseবা Releaseএবং দেখে মনে হচ্ছে: void release() { ref--; if (ref<1) delete this; }


কোনটি ঠিক খনি প্রতিটি প্রকল্পে একবার হচ্ছে ... :-)
cmaster - পুনর্বহাল মনিকা

15

ঠিক আছে, কম্পোনেন্ট অবজেক্ট মডেল (সিওএম) এ delete thisনির্মাণ একটি Releaseপদ্ধতির অংশ হতে পারে যা যখনই আপনি অর্জিত অবজেক্টটি প্রকাশ করতে চান:

void IMyInterface::Release()
{
    --instanceCount;
    if(instanceCount == 0)
        delete this;
}

8

রেফারেন্স-গণনা করা অবজেক্টগুলির জন্য এটি মূল প্রতিমা।

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

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

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


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

1
আপনি কেবলমাত্র আপনার অবজেক্টের স্থিতিশীল এবং স্ট্যাক বরাদ্দকে নিষিদ্ধ করার জন্য ডেস্ট্রাক্টরকে সুরক্ষিত করতে পারেন।
গেম_অভারচার

7

আপনি এটি করতে পারেন। তবে আপনি এটিকে বরাদ্দ করতে পারবেন না। এইভাবে আপনি যে কারণে বলেছিলেন, "আমি দৃষ্টিভঙ্গি পরিবর্তন করতে চাই" খুব সন্দেহজনক বলে মনে হয়। আমার মতে আরও ভাল পদ্ধতি হ'ল সেই দৃষ্টিভঙ্গিকে প্রতিস্থাপনের জন্য যে দৃষ্টিভঙ্গিটি ধারণ করে for

অবশ্যই, আপনি আরআইআইআই অবজেক্টগুলি ব্যবহার করছেন এবং তাই আপনার আসলে ডিলিট কল করার দরকার নেই ... তাই না?


4

এটি একটি পুরানো, উত্তর, প্রশ্ন, কিন্তু @ অ্যালেক্সানড্রে "কেউ কেন এটি করতে চাইবে?" জিজ্ঞাসা করেছিল এবং আমি ভেবেছিলাম যে আমি এই বিকেলে বিবেচনা করছি এমন একটি উদাহরণ ব্যবহার করতে পারি।

উত্তরাধিকার কোড. নগ্ন পয়েন্টারগুলি ব্যবহার করুন ওজেজ * শেষের দিকে মুছে ফেলার সাথে আপত্তি করুন।

দুর্ভাগ্যক্রমে আমার মাঝে মাঝে প্রয়োজন, প্রায়শই নয়, অবজেক্টটি দীর্ঘায়িত করার জন্য।

আমি এটিকে একটি উল্লেখযোগ্য স্মার্ট পয়েন্টার হিসাবে বিবেচনা করছি making তবে পরিবর্তন করার জন্য প্রচুর কোড থাকবে, যদি আমি ref_cnt_ptr<Obj>সর্বত্র ব্যবহার করি । এবং যদি আপনি উলঙ্গ ওবজ * এবং রেফ_সিএনটি_পিটার মিশ্রিত করেন তবে সর্বশেষ রেফ_সিএনটি_পিটার চলে গেলে আপনি অবজেক্টটি স্পষ্টভাবে মুছে ফেলতে পারবেন, যদিও ওবজ * এখনও জীবিত রয়েছে।

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

সুস্পষ্ট_ডিলিটি_রেফ_সিএনটি_সিপি হিসাবে রেফারেন্স গণনাটি বাড়ানো এবং হ্রাস করা হেরফের হয়।

যখন রেফারেন্স গণনাটি সুস্পষ্ট_দেহী_আরফ_সিএনটি_সিপি ডেস্ট্রাক্টরে শূন্য হতে দেখা যায় তখন মুক্ত হয় না।

স্পষ্টভাবে মুছার মতো ক্রিয়াকলাপে যখন রেফারেন্স গণনাটি শূন্য হিসাবে দেখা হয় কেবল তখনই মুক্ত হয়। যেমন কিছুতে:

template<typename T> class explicit_delete_ref_cnt_ptr { 
 private: 
   T* ptr;
   int rc;
   ...
 public: 
   void delete_if_rc0() {
      if( this->ptr ) {
        this->rc--;
        if( this->rc == 0 ) {
           delete this->ptr;
        }
        this->ptr = 0;
      }
    }
 };

ঠিক আছে, এরকম কিছু। কোনও রেফারেন্স গণনা করা পয়েন্টার প্রকারটি আরসি'ড পিটিআর ডিস্ট্রাক্টরটিতে নির্দেশিত বস্তুটি স্বয়ংক্রিয়ভাবে মোছা না হওয়া কিছুটা অস্বাভাবিক। তবে দেখে মনে হচ্ছে এটি নগ্ন পয়েন্টার এবং আরসি'ড পয়েন্টারগুলিকে কিছুটা নিরাপদ করতে পারে।

তবে এখনও পর্যন্ত এটি মুছার প্রয়োজন নেই।

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

class Pointee { 
 private: 
   int rc;
   ...
 public: 
   void delete_if_rc0() {
        this->rc--;
        if( this->rc == 0 ) {
           delete this;
        }
      }
    }
 };

আসলে, এটি মোটেও সদস্য পদ্ধতি হওয়ার দরকার নেই, তবে এটি একটি ফাংশন হতে পারে:

map<void*,int> keepalive_map;
template<typename T>
void delete_if_rc0(T*ptr) {
        void* tptr = (void*)ptr;
        if( keepalive_map[tptr] == 1 ) {
           delete ptr;
        }
};

(বিটিডাব্লু, আমি জানি কোডটি খুব একটা সঠিক নয় - আমি যদি সমস্ত বিবরণ যুক্ত করি তবে এটি কম পঠনযোগ্য হয়ে যায়, তাই আমি এটিকে এভাবেই রেখে যাচ্ছি))


0

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

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