c++ - অবজ - সি++ বই




রিসোর্স অ্যাকুইজিশন দ্বারা বোঝানো হয় কি সূচনা(RAII)? (5)

রিসোর্স অ্যাকুইজিশন দ্বারা বোঝানো হয় কি সূচনা (RAII)?


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

তার খুব হৃদয়ে, মূদ্রাগুলি স্থানীয়, স্বয়ংক্রিয় বস্তুর মধ্যে সম্পদগুলি (মেমরি, খোলা ফাইলগুলি, আনলক করা মু्यूटক্সেস, আপনি-নাম-এটি) এর উপাদানগুলি সঙ্কুচিত করে এবং বস্তুর ধ্বংসকারী যখন বস্তুর ধ্বংস হয় তখন সংস্থাকে ধ্বংস করে দেয়। এটির অন্তর্গত সুযোগটি শেষ:

{
  raii obj(acquire_resource());
  // ...
} // obj's dtor will call release_resource()

অবশ্যই, বস্তু সবসময় স্থানীয়, স্বয়ংক্রিয় বস্তু নয়। তারাও একটি শ্রেণির সদস্য হতে পারে:

class something {
private:
  raii obj_;  // will live and die with instances of the class
  // ... 
};

এই ধরনের বস্তু মেমরি পরিচালনা করে, তারা প্রায়ই "স্মার্ট পয়েন্টার" বলা হয়।

এই অনেক বৈচিত্র আছে। উদাহরণস্বরূপ, প্রথম কোড স্নিপেটগুলিতে প্রশ্ন উঠেছে যে কেউ যদি obj কপি করতে চায় তবে কী হবে। সহজ উপায় অনুলিপি অনুলিপি করা হবে। std::unique_ptr<> , পরবর্তী সি ++ মান দ্বারা বৈশিষ্ট্যযুক্ত স্ট্যান্ডার্ড লাইব্রেরির অংশ হতে একটি স্মার্ট পয়েন্টার, এটি করে।
আরেকটি যেমন স্মার্ট পয়েন্টার, std::shared_ptr বৈশিষ্ট্যগুলি ধারণ করে (একটি গতিশীলভাবে বরাদ্দকৃত বস্তু) "ভাগ করা মালিকানা" বৈশিষ্ট্য। অর্থাৎ, এটি অবাধে অনুলিপি করা যেতে পারে এবং সমস্ত কপি একই বস্তুর উল্লেখ করে। স্মার্ট পয়েন্টার একই বস্তুর কতগুলি কপি উল্লেখ করে তা ধরে রাখে এবং শেষটি ধ্বংস হয়ে গেলে এটি মুছে ফেলবে।
std::auto_ptr দ্বারা একটি তৃতীয় সংস্করণ প্রদর্শিত হয় যা একটি ধরনের সরানো- std::auto_ptr প্রয়োগ করে: একটি বস্তুর মালিক শুধুমাত্র একটি পয়েন্টারের মালিকানাধীন এবং বস্তুর অনুলিপি করার চেষ্টা করলে বস্তুর মালিকানা লক্ষ্যমাত্রার লক্ষ্যবস্তুতে স্থানান্তরিত করতে হবে (সিনট্যাক্স হ্যাকারের মাধ্যমে) অনুলিপি অপারেশন।


একটি RAII ক্লাসে তিনটি অংশ রয়েছে:

  1. সম্পদ ধ্বংসকারী মধ্যে অবতরণ করা হয়
  2. ক্লাসের উদাহরণ বরাদ্দ স্ট্যাক হয়
  3. সম্পদ কনস্ট্রাক্টর অর্জিত হয়। এই অংশটি ঐচ্ছিক, কিন্তু সাধারণ।

RAI "রিসোর্স অধিগ্রহণ শুরু হয়।" RAII এর "সংস্থান অধিগ্রহণ" অংশটি যেখানে আপনি এমন কিছু শুরু করেন যা পরে শেষ হবে, যেমন:

  1. একটি ফাইল খোলা
  2. কিছু মেমরি বরাদ্দ
  3. একটি লক অর্জন

"ইনিশিয়ালাইজেশন" অংশটির অর্থ হল অধিগ্রহণটি একটি বর্গের কন্সট্রকটরের ভিতরে ঘটে।

https://www.tomdalling.com/blog/software-design/resource-acquisition-is-initialisation-raii-explained/


এটি একটি অবিশ্বাস্যভাবে শক্তিশালী ধারণাটির জন্য সত্যিই একটি ভয়ানক নাম এবং সম্ভবত 1 টি জিনিস যা C ++ বিকাশকারীরা অন্যান্য ভাষাগুলিতে স্যুইচ করলে মিস করবেন। Scope-bound resource management হিসাবে এই ধারাকে পুনঃনামকরণ করার চেষ্টা করার জন্য কিছুটা আন্দোলন হয়েছে, যদিও এটি এখনও ধরা হয়নি বলে মনে হচ্ছে।

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

RawResourceHandle* handle=createNewResource();
handle->performInvalidOperation();  // Oops, throws exception
...
deleteResource(handle); // oh dear, never gets called so the resource leaks

রায়ের সাথে এক

class ManagedResourceHandle {
public:
   ManagedResourceHandle(RawResourceHandle* rawHandle_) : rawHandle(rawHandle_) {};
   ~ManagedResourceHandle() {delete rawHandle; }
   ... // omitted operator*, etc
private:
   RawResourceHandle* rawHandle;
};

ManagedResourceHandle handle(createNewResource());
handle->performInvalidOperation();

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


এটি একটি প্রোগ্রামিং idiom যা সংক্ষিপ্তভাবে আপনি মানে

  • একটি বর্গের মধ্যে একটি সম্পদ সংযোজন করে (যার কন্সট্রাকটর সাধারণত - তবে প্রয়োজনীয় নয় ** - সম্পদ অর্জন করে এবং এর ধ্বংসকারী সবসময় এটি প্রকাশ করে)
  • ক্লাসের একটি স্থানীয় উদাহরণ মাধ্যমে সম্পদ ব্যবহার *
  • বস্তু সুযোগ সুযোগ পায় যখন সম্পদ স্বয়ংক্রিয়ভাবে মুক্ত করা হয়

এই গ্যারান্টিটি যে সম্পদটি ব্যবহার করার সময় যা ঘটবে তা নিশ্চিত করে, এটি অবশেষে মুক্ত হবে (স্বাভাবিক প্রত্যাবর্তনের কারণে, ধারণকারী বস্তুর ধ্বংস বা কোনও ব্যতিক্রম ব্যতিক্রম)।

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

* আপডেট: "স্থানীয়" অর্থ একটি স্থানীয় পরিবর্তনশীল হতে পারে, অথবা একটি শ্রেণীর একটি nonstatic সদস্য পরিবর্তনশীল হতে পারে। পরবর্তী ক্ষেত্রে, সদস্য পরিবর্তনশীলটি তার মালিক বস্তুর সাথে শুরু এবং ধ্বংস করা হয়।

** আপডেট 2: @ এসবিআই নির্দেশ করে, সম্পদ - যদিও কনস্ট্রাক্টারের ভিতরে বরাদ্দ করা হয় - বাইরেও বরাদ্দ করা যেতে পারে এবং প্যারামিটার হিসাবে পাস করা যেতে পারে।


ডিজাইন প্যাটার্নস প্রকাশের সাথে সি ++ প্রোগ্রামিং বইটি রাইয়ের বর্ণনা দিয়েছে:

  1. সমস্ত সম্পদ অর্জন
  2. সম্পদ ব্যবহার করে
  3. রিলিজ সম্পদ

কোথায়

  • সম্পদ শ্রেণী হিসাবে প্রয়োগ করা হয়, এবং সব পয়েন্টার তাদের চারপাশে বর্গ wrappers আছে (তাদের স্মার্ট পয়েন্টার তৈরীর)।

  • সম্পদগুলি তাদের নির্মাতাদের আহ্বান করে এবং তাদের বিধ্বংসীদের আহ্বান জানিয়ে নিখুঁতভাবে (অধিগ্রহণের বিপরীত ক্রম অনুসারে) অর্জিত হয়।





raii