কেন স্পষ্টভাবে নির্মাণকারী মুছে ফেলুন?


95

আমি / কখন আমার নির্মাতাকে স্পষ্টভাবে মুছতে চাইব? কারণটি ধরে নিলে এর ব্যবহার প্রতিরোধ করা, কেন এটি কেবল তৈরি করা যায় না private?

class Foo
{ 
  public: 
    Foo() = delete; 
};

14
এটি একরকম দুর্দান্তভাবে যায় = default, এমনকি শ্রেণিও এটি ব্যবহার করতে পারে না এবং আমি ব্যক্তিগতভাবে মুছে ফেলা ফাংশনটির ব্যবহার দেখতে পছন্দ করি ওভার ফাংশন ব্যক্তিগত। প্রাক্তন স্পষ্টতই বলে দেয় "এটি ব্যবহার করার উদ্দেশ্যে নয়" " যদি এর থেকে কিছু বেরিয়ে আসে, শ্রেণি এটি ব্যবহার করতে সক্ষম না হওয়ায় প্রকৃতপক্ষে শব্দার্থগত পার্থক্য তৈরি করে।
ক্রিস

16
আমি সত্যই ভাবি লোকেরা নিকটে ভোট দিয়ে আগ্রাসী হতে শুরু করেছে। আমি দেখতে পাচ্ছি না এটি কীভাবে গঠনমূলক নয়।
লুচিয়ান গ্রিগোর 0

4
@ লুচিয়ানগ্রিগোর: একমত আমি ভাবছিলাম যে সম্প্রদায়টি কেন এত বেশি অনড় হয়ে গেছে। আমি বিন্দু দেখতে পাচ্ছি না।
এড এস।

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

উত্তর:


89

কেমন:

//deleted constructor
class Foo
{ 
  public: 
    Foo() = delete;     
  public:
    static void foo();
};

void Foo::foo()
{
   Foo f;    //illegal
}

বনাম

//private constructor
class Foo
{ 
  private: 
    Foo() {}     
  public:
    static void foo();
};

void Foo::foo()
{
   Foo f;    //legal
}

এগুলি মূলত বিভিন্ন জিনিস। privateআপনাকে বলে যে কেবল শ্রেণীর সদস্যরা সেই পদ্ধতিটি কল করতে পারেন বা সেই পরিবর্তনশীল (বা অবশ্যই বন্ধুরা) অ্যাক্সেস করতে পারেন। এই ক্ষেত্রে, staticসেই শ্রেণীর কোনও পদ্ধতির (বা অন্য কোনও সদস্য) privateকোনও শ্রেণীর একজন কনস্ট্রাক্টরকে কল করা আইনী । এটি মোছা কনস্ট্রাক্টরদের জন্য ধারণ করে না।

নমুনা এখানে


4
আপনি ফু (ইন্টি) ঘোষণা করলে আপনাকে কোনওভাবেই ফু () ঘোষণা করার দরকার নেই। Foo () উত্পন্ন হবে না এবং এভাবে Foo f যাই হোক না কেন অবৈধ। সুতরাং আপনার উদাহরণ মুছে ফেলা কন্সট্রাক্টরের ক্ষেত্রে কেসটি দেখায় না। নিজের জন্য দেখুন - আদর্শ one.com
চিহ্নিত করুন

4
@ চিহ্ন আমি 2 জন কনস্ট্রাক্টর লিখেছি বিষয়টি প্রমাণ করার জন্য। আমি সম্পাদনা করব তাই এটি সবার কাছে পরিষ্কার।
লুচিয়ান গ্রিগোর 0

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

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

4
আমি সত্যই বুঝতে পারি না কীভাবে এটি মূল প্রশ্নের উত্তর দেয়। পোস্টে শিরোনাম এবং ওপির প্রথম প্রশ্নটি ছিল: আমি / কখন আমার নির্মাতাকে স্পষ্টভাবে মুছতে চাইব?
আলেকজান্ডার বলিনস্কি

13

কেন স্পষ্টভাবে নির্মাণকারী মুছে ফেলুন?

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

সি ++ সংকলকটি আপনার জন্য এটি পরীক্ষা করে।

class Foo
{
   public:
       Foo() = delete;
       Foo(int bar) : m_bar(bar) {};
   private:
       int m_bar;
}

এটি - খুব সরলীকৃত - কোড আশ্বাস দেয় যে এর মতো কোনও ইনস্ট্যান্টেশন নেই:Foo foo;


12
মুছে ফেলা ঘোষণা এখানে অপ্রয়োজনীয়। এটি কোনও ব্যবহারকারী-সরবরাহকারীর সাথে স্বয়ংক্রিয়ভাবে মুছে ফেলা হয়েছে
মাইক লুই

4
@MikeLui মন্তব্য নির্মল করতে, মুছে ফেলা ঘোষণা অপ্রয়োজনীয় কম্পাইলারঅন্যান্য প্রোগ্রামারগুলিকে অভিপ্রায় ঘোষণার জন্য এই জাতীয় কোড অন্তর্ভুক্ত করা উচিত যখন অনেকগুলি ক্ষেত্রে রয়েছে ।
জেফ জি

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

কনস্ট্রাক্টর উইচ "= মুছুন" কীওয়ার্ড ঘোষণার সাথে কীভাবে অতিরিক্ত রেখাটি পাই না "ডিফল্ট কনস্ট্রাক্টর" এর চেয়ে ভাল ধারণা ঘোষণা করে ... ঠিক কোনও ডিফল্ট কনস্ট্রাক্টর নয়? নমুনা: আমি আমার কোডে ভেরিয়েবল "ক" ঘোষণা করতে চাই না - "// ইন্ট এ; // লিখতে ভেরিয়েবলটি সংজ্ঞায়িত করার দরকার নেই" বা কোডে এই ভেরিয়েবলটি সম্পর্কে কিছুই লিখতে হবে না?
এজ

2

আমি এলএলভিএমের উত্স কোডে (মুখ্য হিসাবে AlignOf.h এ) 'মুছে ফেলা' হিসাবে ঘোষিত ডিফল্ট সিটারগুলির সাথে দেখা করেছি। সম্পর্কিত শ্রেণীর টেম্পলেটগুলি সাধারণত 'llvm :: বিস্তারিত' নামে একটি বিশেষ নেমস্পেসে থাকে। আমার মনে হয় সেখানে পুরো উদ্দেশ্যটি ছিল তারা class শ্রেণিকে কেবল সহায়ক সহায়ক হিসাবে বিবেচনা করেছিল। তারা কখনও তাদের তাত্ক্ষণিক করার ইচ্ছা করেনি; সংকলন সময়ে চলমান কিছু রূপক কৌশলগুলি সহ কেবলমাত্র অন্যান্য শ্রেণীর টেম্পলেটগুলির প্রসঙ্গে তাদের ব্যবহার করতে।

যেমন এই AlignmentCalcImpl শ্রেণীর টেম্পলেট রয়েছে যা কেবলমাত্র AlignOf নামে মাপের (।) অপারেটরের প্যারামিটার হিসাবে ব্যবহৃত অন্য শ্রেণীর টেম্পলেটের মধ্যে ব্যবহৃত হয়। সংকলন সময়ে এই অভিব্যক্তি মূল্যায়ন করা যেতে পারে; এবং টেমপ্লেটটি ইনস্ট্যান্ট করার দরকার নেই -> তাই এই উদ্দেশ্যটি প্রকাশ করতে ডিফল্ট কর্টর মুছুন না কেন।

তবে এটি কেবল আমার অনুমান।

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