কেন সি ++ 11 " delete
ডি" ফাংশনগুলি ওভারলোড রেজোলিউশনে অংশ নেয় ?
কেন এটি দরকারী? বা অন্য কথায়, এগুলি পুরো মোছার পরিবর্তে কেন লুকানো থাকে?
কেন সি ++ 11 " delete
ডি" ফাংশনগুলি ওভারলোড রেজোলিউশনে অংশ নেয় ?
কেন এটি দরকারী? বা অন্য কথায়, এগুলি পুরো মোছার পরিবর্তে কেন লুকানো থাকে?
উত্তর:
= delete
সিনট্যাক্সের অর্ধেক উদ্দেশ্য হ'ল নির্দিষ্ট পরামিতিগুলির সাথে লোকদের নির্দিষ্ট ফাংশনগুলি কল করতে বাধা দেওয়া। এটি সাধারণত নির্দিষ্ট নির্দিষ্ট পরিস্থিতিতে অন্তর্নিহিত রূপান্তরগুলি রোধ করার জন্য। কোনও নির্দিষ্ট ওভারলোড নিষিদ্ধ করার জন্য, এটি ওভারলোড রেজোলিউশনে অংশ নিতে হবে।
আপনি যে উত্তরটি উদ্ধৃত করেছেন এটি একটি নিখুঁত উদাহরণ দেয়:
struct onlydouble {
onlydouble(std::intmax_t) = delete;
onlydouble(double);
};
যদি delete
পুরোপুরি ফাংশনটি সরিয়ে ফেলা হয়, এটি = delete
সিনট্যাক্সটিকে এর সমান করে তুলবে :
struct onlydouble2 {
onlydouble2(double);
};
আপনি এটি করতে পারেন:
onlydouble2 val(20);
এটি আইনী সি ++। সংকলকটি সমস্ত নির্মাণকারীকে দেখবে; এগুলির মধ্যে কেউই সরাসরি কোনও পূর্ণসংখ্যার প্রকার নেয় না। তবে তাদের মধ্যে একটি এটি অন্তর্নিহিত রূপান্তরের পরে নিতে পারে। সুতরাং এটি কল করব।
onlydouble val(20);
এই না আইনি সি ++। সংকলকটি delete
d সহ সমস্ত কন্সট্রাক্টরকে দেখবে । এটি std::intmax_t
(যা কোনও সংখ্যার আক্ষরিক সাথে হুবহু মিলবে) এর মাধ্যমে একটি সঠিক মিল দেখবে । সুতরাং সংকলক এটি নির্বাচন করবে এবং তারপরে তাত্ক্ষণিকভাবে একটি ত্রুটি জারি করবে, কারণ এটি একটি delete
ডি ফাংশন নির্বাচন করেছে ।
= delete
"" আমি এটিকে নিষেধ করি ", নিছক নয়" "এর অস্তিত্ব নেই" " এটি অনেক শক্তিশালী বক্তব্য।
আমি জিজ্ঞাসা করছিলাম কেন সি ++ স্ট্যান্ডার্ড বলছে = মুছে ফেলার অর্থ "এটি বিদ্যমান নয়" এর পরিবর্তে "আমি এটিকে নিষেধ করি"
এটি কারণ "আমাদের বিদ্যমান নেই" বলতে আমাদের বিশেষ ব্যাকরণের দরকার নেই। আমরা সুনির্দিষ্টভাবে "এই" প্রশ্নবিদ্ধভাবে ঘোষণা না করে এটি স্পষ্টভাবে পেয়েছি। "আমি এই নিষেধ" একটি কনস্ট্রাক্ট যে প্রতিনিধিত্ব করে না পারেন, বিশেষ ব্যাকরণ ছাড়া অর্জন করা। সুতরাং আমরা "আমি এটিকে নিষেধ করি" এবং অন্য জিনিসটি বলার জন্য বিশেষ ব্যাকরণ পাই।
ব্যাকরণ সুস্পষ্টভাবে "এটি বিদ্যমান নেই" থাকার মাধ্যমে আপনি যে কার্যকারিতা অর্জন করবেন তা হ'ল কারওর পরে এটির অস্তিত্ব ঘোষণা করে বাধা দেওয়া। এবং এটি নিজস্ব ব্যাকরণ প্রয়োজন যথেষ্ট দরকারী নয়।
অন্যথায় অনুলিপি দেওয়ার কোনও উপায় নেই যে অনুলিপি নির্মাণকারীর অস্তিত্ব নেই এবং এর অস্তিত্ব অযৌক্তিক দ্বিধা তৈরি করতে পারে।
অনুলিপি নির্মাণকারী একটি বিশেষ সদস্য ফাংশন। প্রতিটি শ্রেণীর সর্বদা একটি অনুলিপি নির্মাণকারী থাকে। ঠিক যেমন তাদের কাছে সর্বদা একটি অনুলিপি অ্যাসাইনমেন্ট অপারেটর, মুভ কনস্ট্রাক্টর ইত্যাদি থাকে have
এই ফাংশন বিদ্যমান; তাদের ফোন করা বৈধ কিনা তা কেবল প্রশ্ন। আপনি যদি = delete
এটির চেষ্টা করে বোঝানোর চেষ্টা করেন যে তাদের অস্তিত্ব নেই, তবে স্পেসিফিকেশনটি কোনও ফাংশনের অস্তিত্ব না থাকার জন্য এর অর্থ কী তা ব্যাখ্যা করতে হবে। এটি কোনও ধারণা নয় যা স্পেসিফিকেশন পরিচালনা করে।
আপনি যদি এমন কোনও ফাংশন কল করার চেষ্টা করেন যা এখনও ঘোষিত / সংজ্ঞায়িত হয়নি, তবে সংকলকটি ত্রুটি করবে। তবে এটি একটি অনির্ধারিত শনাক্তকারীর কারণে ত্রুটি ঘটবে , "ফাংশনটির অস্তিত্ব নেই" ত্রুটির কারণে নয় (এমনকি যদি আপনার সংকলক এটি সেভাবে রিপোর্ট করে)। বিভিন্ন নির্মাণকারী সবাইকে ওভারলোড রেজোলিউশন দ্বারা ডাকা হয়, সুতরাং তাদের "অস্তিত্ব" সেই বিষয়ে পরিচালিত হয়।
প্রতিটি ক্ষেত্রেই হয় শনাক্তকারী বা কনস্ট্রাক্টর / ডেস্ট্রাক্টরের মাধ্যমে ঘোষিত একটি ফাংশন (শনাক্তকারীর মাধ্যমে ঘোষণা করা হয়, কেবলমাত্র টাইপ-আইডেন্টিফায়ার)। অপারেটর ওভারলোডিং সিনট্যাকটিক চিনির পিছনে শনাক্তকারীকে লুকিয়ে রাখে তবে এটি এখনও রয়েছে।
সি ++ স্পেসিফিকেশন কোনও "ফাংশন যা বিদ্যমান নেই" এর ধারণাকে পরিচালনা করতে পারে না। এটি একটি ওভারলোডের অমিলটি পরিচালনা করতে পারে। এটি একটি ওভারলোড অস্পষ্টতা পরিচালনা করতে পারে। কিন্তু কী নেই তা সম্পর্কে এটি জানে না। সুতরাং = delete
কম কার্যকর "ভান করে আমি এই লাইনটি কখনই লিখিনি" এর চেয়ে বেশি কার্যকর "এটিকে ব্যর্থ বলার চেষ্টা" এর পরিপ্রেক্ষিতে সংজ্ঞায়িত করা হয়েছে।
এবং আবার প্রথম অংশটি পুনরায় পড়ুন "ফাংশনের অস্তিত্ব নেই" দিয়ে আপনি এটি করতে পারবেন না । এটি সেইরূপে সংজ্ঞায়িত করার কারণেই এটি অন্য কারণ: কারণ = delete
সিনট্যাক্সের প্রধান ব্যবহারের ক্ষেত্রে অন্যতম হল ব্যবহারকারীকে নির্দিষ্ট প্যারামিটার ধরণের ব্যবহার করতে, স্পষ্টতই কাস্ট করতে বাধ্য করা এবং এর বাইরেও। মূলত, অন্তর্নিহিত ধরণের রূপান্তর ফেইল করতে।
আপনার পরামর্শটি তা করবে না।
= delete
চাইছি " আমি এই সদস্যটির অস্তিত্ব নেই" বোঝাতে চাইছি, যা বোঝায় এটি ওভারলোড রেজোলিউশনে অংশ নিতে পারে না।
= delete
"এই সদস্যটির অস্তিত্ব নেই" বোঝানো হয়, তবে আমি যে প্রথম উদাহরণটি পোস্ট করেছি তা মানুষকে onlydouble
নির্মাণকারীর কাছে পূর্ণসংখ্যার দিক থেকে আটকাতে সক্ষম হবে না , যেহেতু onlydouble
মুছে ফেলা ওভারলোডটি বিদ্যমান থাকবে না । এটি ওভারলোড রেজোলিউশনে অংশ নেবে না এবং সুতরাং এটি আপনাকে পূর্ণসংখ্যার মধ্য দিয়ে যাওয়া থেকে বিরত রাখবে না। যা = delete
সিনট্যাক্সের বিন্দুটির অর্ধেক: এটি বলতে সক্ষম হতে, "আপনি এই ফাংশনটিতে এক্সকে পুরোপুরি পাস করতে পারবেন না।"
=delete
? সর্বোপরি, আমরা ঠিক একই জিনিসটি করে "অনুলিপিযোগ্য" বলতে পারি: অনুলিপি নির্মাণকারী / কার্যনির্বাহী ব্যক্তিগত হিসাবে ঘোষণা করে। এছাড়াও, নোট করুন যে কোনও কিছু ব্যক্তিগত হিসাবে ঘোষণা করা অবিশ্বাস্য নয়; শ্রেণীর মধ্যে কোড এখনও কল করতে পারেন। সুতরাং এটি যেমন হয় না = delete
। না, = delete
সিনট্যাক্স আমাদের এমন কিছু করার অনুমতি দেয় যা এর আগে আরও বেশি স্পষ্ট এবং যুক্তিসঙ্গত উপায়ে অত্যন্ত অসুবিধে এবং অনিবার্য ছিল।
সি ++ ওয়ার্কিং ড্রাফ্ট 2012-11-02 এই নিয়মের পিছনে যুক্তি সরবরাহ করে না, কেবল কয়েকটি উদাহরণ
8.4.3 মুছে ফেলা সংজ্ঞাগুলি [dcl.fct.def.delete]
...
3 [ উদাহরণ : কেউ অ-ডিফল্ট সূচনা এবং অ-অবিচ্ছেদ্য সূচনা প্রয়োগ করতে পারে এর সাথে
struct onlydouble {
onlydouble() = delete; // OK, but redundant
onlydouble(std::intmax_t) = delete;
onlydouble(double);
};
- শেষ উদাহরণ ]
[ উদাহরণস্বরূপ : একটি শ্রেণীর জন্য নতুন কোনও ব্যবহারকারী-ঘোষিত অপারেটরের মুছে ফেলা সংজ্ঞা ব্যবহার করে নির্দিষ্ট নতুন এক্সপ্রেশনগুলিতে কোনও শ্রেণীর ব্যবহার প্রতিরোধ করতে পারে।
struct sometype {
void *operator new(std::size_t) = delete;
void *operator new[](std::size_t) = delete;
};
sometype *p = new sometype; // error, deleted class operator new
sometype *q = new sometype[3]; // error, deleted class operator new[]
- শেষ উদাহরণ ]
[ উদাহরণস্বরূপ : কপি কন্সট্রাক্টর এবং অনুলিপি নিয়োগের অপারেটরের মুছে ফেলা সংজ্ঞাগুলি ব্যবহার করে এবং তারপরে মুভ কনস্ট্রাক্টর এবং মুভ অ্যাসাইনমেন্ট অপারেটরের ডিফল্ট সংজ্ঞা প্রদান করে একটি ক্লাসকে অনিবার্য, অর্থাৎ সরানো কেবলমাত্র তৈরি করতে পারে।
struct moveonly {
moveonly() = default;
moveonly(const moveonly&) = delete;
moveonly(moveonly&&) = default;
moveonly& operator=(const moveonly&) = delete;
moveonly& operator=(moveonly&&) = default;
~moveonly() = default;
};
moveonly *p;
moveonly q(*p); // error, deleted copy constructor
- শেষ উদাহরণ ]