আমি যখন C ++ অনেক আগে শিখেছি তখন আমার কাছে দৃ strongly়ভাবে জোর দেওয়া হয়েছিল যে সি ++ এর পয়েন্টের অংশটি হ'ল লুপগুলিতে যেমন "লুপ-ইনগ্রেন্ট" থাকে, ক্লাসগুলিতেও বস্তুর আজীবনের সাথে যুক্ত থাকে - জিনিসগুলি সত্য হওয়া উচিত যতক্ষণ অবজেক্টটি বেঁচে থাকে কনস্ট্রাক্টর দ্বারা প্রতিষ্ঠিত হওয়া উচিত এবং পদ্ধতিগুলি দ্বারা সংরক্ষণ করা উচিত। আক্রমণকারীদের কার্যকর করতে সহায়তা করার জন্য এনক্যাপসুলেশন / অ্যাক্সেস নিয়ন্ত্রণ রয়েছে। RAII হ'ল একটি জিনিস যা আপনি এই ধারণার সাথে করতে পারেন।
সি ++ 11 যেহেতু এখন আমাদের কাছে মুভ সিমানটিক রয়েছে। যে শ্রেণীর চলন সমর্থন করে, কোনও বস্তু থেকে সরানো তার জীবনকালকে আনুষ্ঠানিকভাবে শেষ করে না - এই পদক্ষেপটি কিছু "বৈধ" অবস্থায় রেখে যাওয়ার কথা।
ক্লাস ডিজাইনের ক্ষেত্রে, আপনি যদি এটি ডিজাইন করেন তবে কি খারাপ অভ্যাসটি বর্গের আক্রমণকারীদের কেবলমাত্র এমন স্থান পর্যন্ত সংরক্ষণ করা যায় যেটি থেকে স্থানান্তরিত হয়েছিল? বা এটি ঠিক আছে যদি এটি আপনাকে এটিকে আরও দ্রুত যেতে দেয়।
এটিকে কংক্রিট করার জন্য, ধরুন আমার কাছে অনুলিপিযোগ্য তবে চলনযোগ্য রিসোর্স ধরণের রয়েছে:
class opaque {
opaque(const opaque &) = delete;
public:
opaque(opaque &&);
...
void mysterious();
void mysterious(int);
void mysterious(std::vector<std::string>);
};
এবং যে কারণেই হোক না কেন, আমার এই সামগ্রীর জন্য একটি অনুলিপিযোগ্য মোড়ক তৈরি করা দরকার, যাতে এটি ব্যবহার করা যায়, সম্ভবত কিছু বিদ্যমান প্রেরণ সিস্টেমে।
class copyable_opaque {
std::shared_ptr<opaque> o_;
copyable_opaque() = delete;
public:
explicit copyable_opaque(opaque _o)
: o_(std::make_shared<opaque>(std::move(_o)))
{}
void operator()() { o_->mysterious(); }
void operator()(int i) { o_->mysterious(i); }
void operator()(std::vector<std::string> v) { o_->mysterious(v); }
};
এই copyable_opaque
অবজেক্টে, নির্মাণের সময়ে প্রতিষ্ঠিত শ্রেণীর o_
একটি আক্রমণকারীটি হ'ল সদস্য সর্বদা একটি বৈধ অবজেক্টের দিকে নির্দেশ করে, যেহেতু কোনও ডিফল্ট কর্টর নেই, এবং একমাত্র কর্টর যা অনুলিপি কর্টার নয় এটি এগুলির গ্যারান্টি দেয়। সমস্ত operator()
পদ্ধতি অনুমান করে যে এই আক্রমণকারীটি ধরে রেখেছে, এবং এটি পরে সংরক্ষণ করবে।
যাইহোক, যদি অবজেক্টটি সরানো হয় তবে o_
তার পরে কিছুই দেখানো হবে না। এবং এই বিন্দুটির পরে, যে কোনও পদ্ধতিতে কলিংয়ের operator()
ফলে ইউবি / ক্রাশ হবে।
যদি বস্তুটি কখনই এখান থেকে সরানো হয় না, তবে ড্যান্টারের কল পর্যন্ত আক্রমণকারীটি সংরক্ষণ করা হবে।
ধরা যাক অনুমানের সাথে, আমি এই ক্লাসটি লিখেছি এবং কয়েক মাস পরে আমার কল্পিত সহকর্মী ইউবি'র অভিজ্ঞতা পেয়েছি কারণ, এমন কিছু জটিল ক্রিয়ায় যেখানে এই কারণগুলিতে প্রচুর পরিমাণে কোনও কারণে ঘুরপাক খাচ্ছিল, তিনি এই বিষয়গুলির মধ্যে একটি থেকে সরে এসে পরবর্তীতে একটিতে ডেকেছিলেন এর পদ্ধতিগুলি। স্পষ্টতই দিন শেষে তার দোষ, কিন্তু এই শ্রেণিটি কি "খারাপভাবে ডিজাইন করা হয়েছে?"
থটস:
জম্বি অবজেক্টগুলি তৈরি করতে এটি সি ++ এ সাধারণত খারাপ ফর্ম যা আপনি তাদের স্পর্শ করলে বিস্ফোরিত হয়।
আপনি যদি কিছু অবজেক্ট তৈরি করতে না পারেন, আক্রমণকারীদের প্রতিষ্ঠা করতে না পারেন তবে ctor থেকে একটি ব্যতিক্রম নিক্ষেপ করুন। যদি আপনি কোনও পদ্ধতিতে আক্রমণকারীদের সংরক্ষণ করতে না পারেন তবে কোনওভাবে কোনও ত্রুটি সংকেত করুন এবং রোল-ব্যাক করুন। সরানো-থেকে আসা বস্তুর জন্য এটি আলাদা হওয়া উচিত?শিরোনামে "এই বস্তুটি সরিয়ে নেওয়ার পরে, কেবল এটি নথিভুক্ত করার পক্ষে কি যথেষ্ট?" শিরোনামে এটি ধ্বংস করা ছাড়া এটির সাথে অন্য কিছু করা অবৈধ (ইউবি)?
এটি প্রতিটি পদ্ধতির কলটিতে বৈধ কিনা তা ধারাবাহিকভাবে দাবি করা আরও ভাল?
তাই ভালো:
class copyable_opaque {
std::shared_ptr<opaque> o_;
copyable_opaque() = delete;
public:
explicit copyable_opaque(opaque _o)
: o_(std::make_shared<opaque>(std::move(_o)))
{}
void operator()() { assert(o_); o_->mysterious(); }
void operator()(int i) { assert(o_); o_->mysterious(i); }
void operator()(std::vector<std::string> v) { assert(o_); o_->mysterious(v); }
};
দাবিগুলি আচরণের যথেষ্ট পরিমাণে উন্নতি করে না এবং এগুলি একটি ধীরগতির কারণ হয়। যদি আপনার প্রকল্পটি "রিলিজ বিল্ড / ডিবাগ বিল্ড" স্কিমটি ব্যবহার না করে কেবল সর্বদা দৃser়তার সাথে চলমান থাকে, তবে আমি অনুমান করি এটি আরও আকর্ষণীয়, যেহেতু আপনি রিলিজ বিল্ডের চেকগুলির জন্য অর্থ প্রদান করেন না। আপনার যদি ডিবাগ বিল্ডগুলি না থাকে তবে এটি বেশ অপ্রত্যাশিত বলে মনে হয়।
- ক্লাসটি অনুলিপিযোগ্য করা ভাল তবে কি অচল নয়?
এটিও খারাপ বলে মনে হচ্ছে এবং এটি একটি পারফরম্যান্স হিটের কারণ, তবে এটি "আক্রমণকারী" ইস্যুকে সোজা উপায়ে সমাধান করে।
আপনি এখানে প্রাসঙ্গিক "সেরা অনুশীলন" হিসাবে বিবেচনা করবেন?