অনুলিপি নির্মাণকারী অক্ষম করুন


173

আমার একটি ক্লাস রয়েছে:

class SymbolIndexer {
protected:
  SymbolIndexer ( ) { }

public:
  static inline SymbolIndexer & GetUniqueInstance ( ) 
  { 
    static SymbolIndexer uniqueinstance_ ;
    return uniqueinstance_ ; 
  }
};

কোডটি অক্ষম করতে আমি কীভাবে এটি সংশোধন করব:

SymbolIndexer symbol_indexer_ = SymbolIndexer::GetUniqueInstance ( );

এবং কেবল কোডের অনুমতি দিন:

SymbolIndexer & ref_symbol_indexer_ = SymbolIndexer::GetUniqueInstance ( );

1
বিটিডব্লিউ, এটি কি উত্তরাধিকারের বিধান সহ একক একক (সুরক্ষিত)?
আর মার্টিনহো ফার্নান্দেস

আপনার কোডে আমার সন্দেহ আছে যতবার না আলাদা ঘটনা তৈরি হবে আমার মনে হয় GetUniqueInstance () সর্বদা একই বস্তুর রেফারেন্স দেবে।
প্রথম শাহ

উত্তর:


286

আপনি অনুলিপি নির্মাণকারীকে ব্যক্তিগত করতে পারেন এবং কোনও বাস্তবায়ন সরবরাহ করতে পারেন:

private:
    SymbolIndexer(const SymbolIndexer&);

বা সি ++ এ, স্পষ্টভাবে এটি নিষিদ্ধ:

SymbolIndexer(const SymbolIndexer&) = delete;

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

1
@ পলুউস I86 আমি আপনার পদ্ধতির পছন্দ করি তবে আমি এটির সাথে পুরোপুরি প্রতিশ্রুতি রাখব না কারণ আমি মনে করি যে এই প্যাটার্ন অনুসরণ করে সময় ব্যয় করা ত্রুটিগুলি দ্বারা সংরক্ষণ করা সময়ের চেয়ে বেশি। যখনই নিশ্চিত না হয় আমি কেবল অনুলিপি করতে নিষেধ করি।
টোমা জ্যাটো - মনিকা

@ pauluss86 এটি মুলত মরচে কাজ করে: মুন-বাই-ডিফল্ট (এবং কনস্ট-বাই-ডিফল্ট)। আমার মতে খুব সহায়ক।
কাপিচু

33

আপনি যদি একাধিক উত্তরাধিকার মনে করেন না (তবে এটি এতটা খারাপ নয়) তবে আপনি প্রাইভেট কপি কনস্ট্রাক্টর এবং অ্যাসাইনমেন্ট অপারেটর সহ সাধারণ ক্লাস লিখতে পারেন এবং অতিরিক্তভাবে এটি সাবক্লাস করতে পারেন:

class NonAssignable {
private:
    NonAssignable(NonAssignable const&);
    NonAssignable& operator=(NonAssignable const&);
public:
    NonAssignable() {}
};

class SymbolIndexer: public Indexer, public NonAssignable {
};

জিসিসির জন্য এটি নিম্নলিখিত ত্রুটি বার্তা দেয়:

test.h: In copy constructor ‘SymbolIndexer::SymbolIndexer(const SymbolIndexer&)’:
test.h: error: ‘NonAssignable::NonAssignable(const NonAssignable&)’ is private

যদিও প্রতিটি সংকলকটিতে এটি কাজ করার জন্য আমি খুব বেশি নিশ্চিত নই। একটি সম্পর্কিত প্রশ্ন আছে , কিন্তু এখনও কোন উত্তর নেই।

UPD:

সি ++ 11 এ আপনি NonAssignableনিম্নরূপ ক্লাসও লিখতে পারেন :

class NonAssignable {
public:
    NonAssignable(NonAssignable const&) = delete;
    NonAssignable& operator=(NonAssignable const&) = delete;
    NonAssignable() {}
};

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

test.cpp: error: use of deleted function
          ‘SymbolIndexer& SymbolIndexer::operator=(const SymbolIndexer&)’
test.cpp: note: ‘SymbolIndexer& SymbolIndexer::operator=(const SymbolIndexer&)’
          is implicitly deleted because the default definition would
          be ill-formed:

UPD:

বুস্টের ইতিমধ্যে একই উদ্দেশ্যে একটি ক্লাস রয়েছে, আমার ধারণা এটি এটি একইভাবে কার্যকর করা হয়েছে। ক্লাস বলা হয় boost::noncopyableএবং নিম্নলিখিত হিসাবে ব্যবহার করা বোঝানো হয়:

#include <boost/core/noncopyable.hpp>

class SymbolIndexer: public Indexer, private boost::noncopyable {
};

যদি আপনার প্রকল্পের নীতিটি এটির অনুমতি দেয় তবে আমি বুস্টের সমাধানটি আটকে রাখার পরামর্শ দেব। আরও তথ্যের জন্য আরেকটি boost::noncopyableসম্পর্কিত প্রশ্নও দেখুন।


তা হতে হবে না NonAssignable(const NonAssignable &other);?
ট্রয়সিফ

আমি মনে করি যদি এই প্রশ্নটি সি ++ 11 deleteকীওয়ার্ড সিনট্যাক্সে আপডেট করা হয় তবে আরও বেশি উপায়ে পাবেন ।
টোমা জ্যাটো - মনিকা

@ টোমাজাটো: ধারণাটি হ'ল কপি কন্সট্রাক্টর এবং অ্যাসাইনমেন্ট অপারেটরকে উপস্থিত রাখা, তবে ব্যক্তিগত। আপনি যদি deleteসেগুলি করেন তবে এটি কাজ করা বন্ধ করে দেয় (আমি স্রেফ পরীক্ষা করেছি)।
অগ্নিগুরাফিকু

@ টোমাজাটো: আহ, দুঃখিত, আমার পরীক্ষার পদ্ধতিটি কিছুটা ভুল ছিল। মুছে ফেলাও কাজ করে। এক মিনিটের মধ্যে উত্তর আপডেট করবে।
ফায়ারগুফিকু

3
@ ট্রয়সেফ: const Class&এবং Class const&বেশ একইরকম। পয়েন্টারগুলির জন্য আপনার এমনকি টাইপও হতে পারে Class const * const
ফায়ারগুরফিকু

4

SymbolIndexer( const SymbolIndexer& )প্রাইভেট করুন আপনি যদি কোনও রেফারেন্স অর্পণ করেন, আপনি অনুলিপি করছেন না।

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