ক্লাস 'ফাংশন ঘোষণার পরে "ডিফল্ট" অর্থ কী?


221

আমি defaultক্লাসে ঘোষণাপত্রের ফাংশনগুলির পাশে ব্যবহার করেছি । এটার কাজ কি?

class C {
  C(const C&) = default;
  C(C&&) = default;
  C& operator=(const C&) & = default;
  C& operator=(C&&) & = default;
  virtual ~C() { }
};

26
অ্যাসাইনমেন্ট অপারেটরের ঘোষণায় "=" এর আগে "&" কী করবে?
dshin

উত্তর:


249

এটি একটি নতুন সি ++ 11 বৈশিষ্ট্য

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

আপনি = deleteযে নির্দিষ্টকরণটি স্বয়ংক্রিয়ভাবে সেই ফাংশনটি তৈরি করতে চান না তা উল্লেখ করতে আপনি এটিও ব্যবহার করতে পারেন।

মুভ কনস্ট্রাক্টর এবং মুভ অ্যাসাইনমেন্ট অপারেটরগুলির প্রবর্তনের সাথে সাথে, কন্সট্রাক্টর, ডিস্ট্রাক্টর এবং অ্যাসাইনমেন্ট অপারেটরগুলির স্বয়ংক্রিয় সংস্করণগুলি উত্পন্ন করার নিয়মগুলি বেশ জটিল হয়ে উঠেছে। আপনার নিয়মগুলি মনে রাখার দরকার নেই বলে জিনিসগুলি ব্যবহার = defaultএবং = deleteসহজ করে তোলে: আপনি যা করতে চান তা কেবলই বলে যান।


17
= deleteআরও শক্তিশালী: এর অর্থ, এই ফাংশনটি ব্যবহার করা নিষিদ্ধ, যদিও এটি এখনও ওভারলোড রেজোলিউশনে অংশ নেয়।
উত্সাহক ২ 4

2
তবে, আমরা যদি সংকলক জেনারেট সংজ্ঞাটি ব্যবহার করতে চাই, তবে "ফাংশনটি প্রথমে লেখার পরে এটি ডিফল্টরূপে নির্ধারণ করা" না করে সেই ফাংশনটি লেখাটি বাদ দেওয়া উচিত নয়?
মায়াঙ্ক জিন্দাল

47

এটি একটি নতুন সি ++ 0 এক্স বৈশিষ্ট্য যা সংকলককে সংশ্লিষ্ট কনস্ট্রাক্টর বা অ্যাসাইনমেন্ট অপারেটরের ডিফল্ট সংস্করণ তৈরি করতে বলে, অর্থাত্ প্রতিটি সদস্যের জন্য অনুলিপি বা পদক্ষেপের ক্রিয়া সম্পাদন করে one এটি দরকারী কারণ মুভ কনস্ট্রাক্টর সর্বদা ডিফল্টরূপে উত্পন্ন হয় না (যেমন আপনার যদি কাস্টম ডিস্ট্রাক্টর থাকে তবে) অনুলিপি নির্মাণকারী (এবং একইভাবে কার্যনির্বাহার জন্য), তবে লেখার জন্য অ-তুচ্ছ কিছু না থাকলে এটি আরও ভাল সংকলক হ্যান্ডেল করুন প্রতি বার এটি নিজের বানান চেয়ে।

এছাড়াও খেয়াল করুন যে আপনি যদি অন্য কোনও ডিফল্ট কনস্ট্রাক্টর সরবরাহ করেন তবে একটি ডিফল্ট কনস্ট্রাক্টর উত্পন্ন হবে না। আপনি যদি এখনও ডিফল্ট কনস্ট্রাক্টর চান, আপনিও এই সংশ্লেষটি সংকলকটি তৈরি করতে ব্যবহার করতে পারেন।

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

বিস্তারিত জানার জন্য মানক বিভাগের 12.8 দেখুন।


5
যদিও এটা না শুধুমাত্র কনস্ট্রাকটর এবং বরাদ্দকরণ জন্য, কিন্তু প্রযোজ্য operator new/new[], operator delete/delete[]এবং তাদের overloads।
সেবাস্তিয়ান মাচ

21

এটি সি ++ 11 এ নতুন, এখানে দেখুন । আপনি যদি কোনও নির্মাণকারীকে সংজ্ঞায়িত করেন তবে এটি অন্যদের জন্য ডিফল্ট ব্যবহার করতে চান তবে এটি বেশ কার্যকর হতে পারে। প্রাক-সি ++ 11 আপনাকে একবার একজন নির্ধারিত করে সমস্ত কন্সট্রাক্টরকে সংজ্ঞায়িত করতে হবে, এমনকি সেগুলি ডিফল্টের সমতুল্য হয়।

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


5
দ্বিতীয় অনুচ্ছেদ সম্পর্কে, আপনি একটি উদাহরণ প্রদান করতে পারেন?
জন স্মিথ

11

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


1

সি ++ 17 এন 4659 মানক খসড়া

https://github.com/cplusplus/draft/blob/master/papers/n4659.pdf 11.4.2 "স্পষ্টতই খেলাপি ডিফল্ট":

1 ফর্ম একটি ফাংশন সংজ্ঞা:

attribute-specifier-seq opt decl-specifier-seq opt declarator virt-specifier-seq opt = default ;

একে সুস্পষ্টভাবে খেলাপী সংজ্ঞা বলা হয়। একটি ফাংশন যা স্পষ্টতই খেলাপি হয় shall

  • (1.1) - একটি বিশেষ সদস্য ফাংশন হতে,

  • (১.২) - একই ঘোষিত ফাংশন ধরণের (সম্ভবত পৃথক পৃথক রেফ-কোয়ালিফায়ার ব্যতীত এবং একটি অনুলিপি নির্মাণকারী বা অনুলিপি অ্যাসাইনমেন্ট অপারেটরের ক্ষেত্রে, প্যারামিটারের ধরনটি "নন-কনস্ট্যান্ট টি-এর রেফারেন্স" হতে পারে, যেখানে টি সদস্য ফাংশনের শ্রেণীর নাম) যেন এটি স্পষ্টভাবে ঘোষণা করা হয়েছে এবং

  • (1.3) - ডিফল্ট আর্গুমেন্ট নেই।

2 একটি সুস্পষ্টভাবে ডিফল্ট ফাংশন যা মুছে ফেলা হিসাবে সংজ্ঞায়িত করা হয় না কেবল তখনই এটি কনস্টেক্সপ্র হিসাবে ঘোষিত হতে পারে যদি তা স্পষ্টভাবে কনস্টেক্সপ্র হিসাবে ঘোষণা করা হত। যদি কোনও ক্রিয়াকলাপটি তার প্রথম ঘোষণার ক্ষেত্রে স্পষ্টতই খেলাপি হয়, তবে অন্তর্নিহিত ঘোষণাপত্রটি যদি তা স্পষ্টতই কনস্টেক্সার্প হিসাবে বিবেচিত হয়।

3 যদি কোনও ফাংশন যা স্পষ্টভাবে খেলাপি হয়, তাকে নোসেপ্ট-স্পেসিফায়ার দিয়ে ঘোষণা করা হয় যা অন্তর্নিহিত ঘোষণার (18.4) এর মতো ব্যতিক্রম স্পেসিফিকেশন তৈরি করে না, তবে

  • (৩.১) - যদি ফাংশনটি তার প্রথম ঘোষণায় স্পষ্টতই খেলাপি হয়, তবে এটি মুছে ফেলা হিসাবে সংজ্ঞায়িত করা হয়;

  • (3.2) - অন্যথায়, প্রোগ্রামটি দুর্গঠিত।

4 [উদাহরণ:

struct S {
  constexpr S() = default;            // ill-formed: implicit S() is not constexpr
  S(int a = 0) = default;             // ill-formed: default argument
  void operator=(const S&) = default; // ill-formed: non-matching return type
  ~ S() noexcept(false) = default;    // deleted: exception specification does not match
private:
  int i;                              // OK: private copy constructor
  S(S&);
};
S::S(S&) = default;                   // OK: defines copy constructor

- শেষ উদাহরণ]

5 সুস্পষ্টভাবে ডিফল্ট ফাংশন এবং সুস্পষ্টভাবে ঘোষিত ফাংশনগুলিকে সম্মিলিতভাবে ডিফল্ট ফাংশন বলা হয় এবং বাস্তবায়ন তাদের জন্য নিখুঁত সংজ্ঞা প্রদান করে (15.1 15.4, 15.8), যার অর্থ তাদের মুছে ফেলা হিসাবে সংজ্ঞায়িত করা হতে পারে। কোনও ফাংশনটি ব্যবহারকারী-সরবরাহিত হয় যদি এটি ব্যবহারকারী-ঘোষিত হয় এবং তার প্রথম ঘোষণায় স্পষ্টতই খেলাপি বা মুছে ফেলা হয় না। একটি ব্যবহারকারী দ্বারা সরবরাহিত স্পষ্টতই-খেলাপী কার্য (যেমন, তার প্রথম ঘোষণার পরে স্পষ্টতই খেলাপী) এমন স্থানে সংজ্ঞায়িত হয় যেখানে এটি স্পষ্টতই খেলাপি হয়; যদি এই জাতীয় কোনও ফাংশন স্পষ্টভাবে মুছে ফেলা হিসাবে সংজ্ঞায়িত করা হয়, তবে প্রোগ্রামটি গঠনযুক্ত। [দ্রষ্টব্য: কোনও ক্রিয়াকলাপটিকে তার প্রথম ঘোষণার পরে খেলাপি হিসাবে ঘোষিত করা একটি কার্যকর কোড বেসে স্থিতিশীল বাইনারি ইন্টারফেস সক্ষম করার সময় কার্যকর কার্যকরকরণ এবং সংক্ষিপ্ত সংজ্ঞা প্রদান করতে পারে। - শেষ নোট]

[[উদাহরণ:

struct trivial {
  trivial() = default;
  trivial(const trivial&) = default;
  trivial(trivial&&) = default;
  trivial& operator=(const trivial&) = default;
  trivial& operator=(trivial&&) = default;
  ~ trivial() = default;
};
struct nontrivial1 {
  nontrivial1();
};
nontrivial1::nontrivial1() = default;       // not first declaration

- শেষ উদাহরণ]

তারপরে প্রশ্নটি হল অবশ্যই কোন কার্যগুলি সুস্পষ্টভাবে ঘোষণা করা যেতে পারে এবং কখন তা ঘটে, যা আমি এখানে ব্যাখ্যা করেছি:

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