সি ++ এ নিরাপদ ইন্টারফেসের প্যাটার্নটি কী


22

দ্রষ্টব্য: নীচেরটি সি ++ 03 কোড, তবে আমরা পরের দুই বছরে সি ++ 11 এ যাওয়ার একটি প্রত্যাশা রাখি, তাই আমাদের অবশ্যই এটি মাথায় রাখতে হবে।

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

এই কোডটি অবশ্যই সংকলন করা উচিত নয়!

void foo(SomeInterface & a, SomeInterface & b)
{
   SomeInterface c ;               // must not be default-constructible
   SomeInterface d(a);             // must not be copy-constructible
   a = b ;                         // must not be assignable
}

উপরের সমস্ত আচরণগুলি কাটানোর ক্ষেত্রে তাদের সমস্যার উত্সটি খুঁজে বের করে : বিমূর্ত ইন্টারফেস (বা শ্রেণিবিন্যাসে লিফ-লিফ ক্লাস) গঠনযোগ্য বা কপিযোগ্য / অ্যাসাইয়েবল হওয়া উচিত নয়, যদি উত্পন্ন শ্রেণিটি হতে পারে তবে ইভিএন।

0 তম সমাধান: বেসিক ইন্টারফেস

class VirtuallyDestructible
{
   public :
      virtual ~VirtuallyDestructible() {}
} ;

এই সমাধানটি সরল, এবং কিছুটা নির্বোধ: এটি আমাদের সমস্ত প্রতিবন্ধকতা ব্যর্থ করে: এটি ডিফল্ট-নির্মিত, অনুলিপি-নির্মিত এবং অনুলিপি-নির্ধারিত হতে পারে (আমি মুভ কনস্ট্রাক্টর এবং অ্যাসাইনমেন্ট সম্পর্কেও নিশ্চিত নই, তবে এখনও আমার 2 বছর সময় আছে এটি).

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

তো, না ...

1 ম সমাধান: বুস্ট :: নন কপি

class VirtuallyDestructible : boost::noncopyable
{
   public :
      virtual ~VirtuallyDestructible() {}
} ;

এই সমাধানটি সেরা, কারণ এটি সরল, পরিষ্কার এবং সি ++ (কোনও ম্যাক্রো নেই) is

সমস্যাটি হ'ল এটি এখনও সেই নির্দিষ্ট ইন্টারফেসের জন্য কাজ করে না কারণ ভার্চুয়ালি কনস্ট্রাক্টেবল এখনও ডিফল্ট-নির্মিত হতে পারে

  1. আমরা ডেস্ট্রাক্টরকে খাঁটি ভার্চুয়াল ঘোষণা করতে পারি না কারণ আমাদের এটি ইনলাইন রাখতে হবে এবং আমাদের কিছু সংকলক এটি হজম করবে না।
  2. হ্যাঁ, এই শ্রেণীর একমাত্র পয়েন্টটি প্রয়োগকারীদের কার্যত ধ্বংসাত্মক করে তোলা, এটি বিরল ঘটনা।

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

এটি জিরো রুলের বিপরীতে যায়, যেখানে আমরা যেতে চাই: যদি ডিফল্ট বাস্তবায়ন ঠিক থাকে, তবে আমাদের এটি ব্যবহার করতে সক্ষম হওয়া উচিত।

দ্বিতীয় সমাধান: তাদের সুরক্ষিত করুন!

class MyInterface
{
   public :
      virtual ~MyInterface() {}

   protected :
      // With C++11, these methods would be "= default"
      MyInterface() {}
      MyInterface(const MyInterface & ) {}
      MyInterface & operator = (const MyInterface & ) { return *this ; }
} ;

এই প্যাটার্নটি আমাদের ছিল এমন প্রযুক্তিগত প্রতিবন্ধকতাগুলি অনুসরণ করে (কমপক্ষে ব্যবহারকারীর কোডে): মাইআইন্টারফেসটি ডিফল্ট-নির্মাণ করা যায় না, অনুলিপি তৈরি করা যায় না এবং অনুলিপিও দেওয়া যায় না।

এছাড়াও, এটি ক্লাস বাস্তবায়নে কোনও কৃত্রিম বাধা আরোপ করে না , যা জিরো রুল অনুসরণ করতে বা এমনকি নির্ধারিত কিছু সি ++ 11/14 এ "= ডিফল্ট" হিসাবে নির্ধারিত কিছু নির্মাতাকে / অপারেটরকে মুক্ত করতে পারে।

এখন, এটি বেশ ভার্জোজ এবং একটি বিকল্পের জন্য ম্যাক্রো ব্যবহার করা হবে, এরকম কিছু:

class MyInterface
{
   public :
      virtual ~MyInterface() {}

   protected :
      DECLARE_AS_NON_SLICEABLE(MyInterface) ;
} ;

সুরক্ষিত অবশ্যই ম্যাক্রোর বাইরে থাকতে হবে (কারণ এর কোনও সুযোগ নেই)।

সঠিকভাবে "নেমস্পিড" (এটি আপনার সংস্থা বা পণ্যটির নামের সাথে উপসর্গযুক্ত), ম্যাক্রোটি নিরীহ হতে হবে।

এবং সুবিধাটি হ'ল কোডটি একটি ইন্টারফেসে বর্ণিত হয়, পরিবর্তে সমস্ত ইন্টারফেসে অনুলিপি করা হয়। ভবিষ্যতে মুভ-কনস্ট্রাক্টর এবং মুভ-অ্যাসাইনমেন্টটি স্পষ্টভাবে একইভাবে অক্ষম করা উচিত, কোডে এটি খুব হালকা পরিবর্তন হবে।

উপসংহার

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

দয়া করে মনে রাখবেন যে এটি এমন একটি প্যাটার্ন যা নবজাতকদের (অন্যদের মধ্যে) জন্য একটি গাইডলাইন হিসাবে কাজ করবে, সুতরাং একটি সমাধান যেমন: "প্রতিটি ক্ষেত্রে এর প্রয়োগ হওয়া উচিত" এটি একটি व्यवहार্য সমাধান নয়।

অনুগ্রহ এবং ফলাফল

প্রশ্নের উত্তর দেওয়ার জন্য সময় ব্যয় করা, এবং উত্তরগুলির প্রাসঙ্গিকতার কারণে আমি কর্ড্পকে অনুদান প্রদান করি ।

আমার সমস্যার সমাধানটি সম্ভবত এরকম কিছুতে যাবে:

class MyInterface
{
   DECLARE_CLASS_AS_INTERFACE(MyInterface) ;

   public :
      // the virtual methods
} ;

... নিম্নলিখিত ম্যাক্রো সহ:

#define DECLARE_CLASS_AS_INTERFACE(ClassName)                                \
   public :                                                                  \
      virtual ~ClassName() {}                                                \
   protected :                                                               \
      ClassName() {}                                                         \
      ClassName(const ClassName & ) {}                                       \
      ClassName & operator = (const ClassName & ) { return *this ; }         \
   private :

নিম্নলিখিত সমস্যার কারণে এটি আমার সমস্যার একটি কার্যকর সমাধান:

  • এই শ্রেণিটি তাত্ক্ষণিকভাবে চালু করা যায় না (নির্মাণকারীরা সুরক্ষিত)
  • এই শ্রেণিটি কার্যত ধ্বংস হতে পারে
  • উত্তরাধিকারসূত্রে প্রাপ্ত ক্লাসগুলিতে অযৌক্তিক বাধা না চাপিয়ে এই শ্রেণিটি উত্তরাধিকার সূত্রে প্রাপ্ত হতে পারে (যেমন উত্তরাধিকার সূত্রে ডিফল্টরূপে অনুলিপিযোগ্য হতে পারে)
  • ম্যাক্রোর ব্যবহারের অর্থ হল ইন্টারফেস "ঘোষণা" সহজেই সনাক্তযোগ্য (এবং সন্ধানযোগ্য), এবং এর কোডটি এক জায়গায় ফ্যাক্টর করা হয়েছে যাতে এটি পরিবর্তন করা সহজতর হয় (উপযুক্ত উপসর্গযুক্ত নামটি অনাকাঙ্ক্ষিত নাম সংঘাতগুলি সরিয়ে দেবে)

মনে রাখবেন যে অন্যান্য উত্তরগুলি মূল্যবান অন্তর্দৃষ্টি দিয়েছে। আপনাকে যারা ধন্যবাদ জানিয়েছে তাদের সবাইকে ধন্যবাদ।

মনে রাখবেন যে আমি অনুমান করি যে আমি এখনও এই প্রশ্নটিতে অন্য একটি অনুগ্রহ রাখতে পারি, এবং আমি যথেষ্ট আলোকিত উত্তরকে আমি মূল্যবান বলে মনে করি যে আমি একটি দেখতে পেলাম, আমি কেবল উত্তরটি বরাদ্দ করার জন্য একটি খোলাখুলি খুলব।


5
আপনি কেবল ইন্টারফেসে খাঁটি ভার্চুয়াল ফাংশন ব্যবহার করতে পারবেন না? virtual void bar() = 0;উদাহরণ স্বরূপ? এটি আপনার ইন্টারফেসটিকে তাত্ক্ষণিকভাবে আটকাতে বাধা দেবে।
মরউভেন

@ মোরওয়েন: প্রশ্নে যেমন বলা হয়েছে, এটি 99% কেস সমাধান করবে (সম্ভব হলে আমি 100% এর লক্ষ্য রাখি)। এমনকি যদি আমরা অনুপস্থিত 1% উপেক্ষা করা বেছে নিই, তবে এটি অ্যাসাইনমেন্ট স্লাইসিংয়ের সমাধান করবে না। সুতরাং, না, এটি একটি ভাল সমাধান নয়।
প্যারাসেবল

@ মরওভেন: সিরিয়াসলি? ... :- ডি ... আমি প্রথম এই প্রশ্নটি স্ট্যাকওভারফ্লোতে লিখেছিলাম এবং তারপরে জমা দেওয়ার ঠিক আগে আমার মন পরিবর্তন করেছি। আপনি কি বিশ্বাস করেন যে আমার এটি এখানে মুছে ফেলা উচিত, এবং এটি এসওতে জমা দিতে হবে?
প্যারাসেবল

যদি আমি ঠিক আছি তবে আপনার যা দরকার তা হ'ল virtual ~VirtuallyDestructible() = 0এবং ইন্টারফেস ক্লাসগুলির ভার্চুয়াল উত্তরাধিকার (কেবল বিমূর্ত সদস্যের সাথে)। আপনি সম্ভবত ভার্চুয়ালডেস্ট্রাক্টেবল বাদ দিতে পারেন।
ডায়েটার ল্যাকিং

5
@ পেয়ারসাবল: সংকলক যদি খাঁটি ভার্চুয়াল ক্লাসগুলিতে চাপ দেয় তবে এটি আবর্জনার মধ্যে রয়েছে। একটি আসল ইন্টারফেস হ'ল সংজ্ঞা বিশুদ্ধ ভার্চুয়াল।
কেউ

উত্তর:


13

সি ++ তে একটি ইন্টারফেস তৈরির আধ্যাত্মিক উপায় হ'ল একে খাঁটি ভার্চুয়াল ডেস্ট্রাক্টর দেওয়া। এটি নিশ্চিত করে

  • ইন্টারফেস শ্রেণীর কোনও নজির নিজেই তৈরি করা যায় না, কারণ সি ++ আপনাকে বিমূর্ত শ্রেণীর উদাহরণ তৈরি করতে দেয় না। এটি গঠনমূলক না প্রয়োজনীয়তা (ডিফল্ট এবং অনুলিপি উভয়) এর যত্ন নেয়।
  • deleteইন্টারফেসে একটি পয়েন্টারটিতে কল করা সঠিক কাজ করে: এটি সেই উদাহরণের জন্য সর্বাধিক উদ্ভূত শ্রেণীর ডেস্ট্রাক্টরকে কল করে।

কেবল খাঁটি ভার্চুয়াল ডেস্ট্রাক্টর থাকা ইন্টারফেসের রেফারেন্সে অ্যাসাইনমেন্ট আটকাবে না। আপনার যদি এটির পাশাপাশি ব্যর্থ হওয়ার প্রয়োজন হয় তবে আপনার ইন্টারফেসে অবশ্যই একটি সুরক্ষিত অ্যাসাইনমেন্ট অপারেটর যুক্ত করতে হবে।

যে কোনও সি ++ সংকলককে এই জাতীয় শ্রেণি / ইন্টারফেস হ্যান্ডেল করতে সক্ষম হওয়া উচিত (সমস্তই একটি শিরোনামের ফাইলে):

class MyInterface {
public:
  virtual ~MyInterface() = 0;
protected:
  MyInterface& operator=(const MyInterface&) { return *this; } // or = default for C++14
};

inline MyInterface::~MyInterface() {}

যদি আপনার কাছে এমন একটি সংকলক থাকে যা এটির উপরে চাপ দেয় (যার অর্থ এটি অবশ্যই প্রাক-সি ++ 98 হওয়া উচিত) তবে আপনার বিকল্প 2 (সুরক্ষিত কনস্ট্রাক্টর থাকা) ভাল দ্বিতীয়-সেরা।

boost::noncopyableএই কাজের জন্য ব্যবহার করা ঠিক নয়, কারণ এটি এই বার্তাটি প্রেরণ করে যে শ্রেনীর সমস্ত শ্রেণি অনুলিপিযোগ্য হওয়া উচিত এবং এটি আরও অভিজ্ঞ বিকাশকারীদের জন্য বিভ্রান্তি তৈরি করতে পারে যারা এইভাবে ব্যবহারের জন্য আপনার উদ্দেশ্যগুলির সাথে পরিচিত হবে না।


If you need [prevent assignment] to fail as well, then you must add a protected assignment operator to your interface.: এটাই আমার সমস্যার মূল। অ্যাসাইনমেন্টটি সমর্থন করার জন্য যেখানে আমার ইন্টারফেসের প্রয়োজন সেগুলি অবশ্যই বিরল। অন্যদিকে, যেসব ক্ষেত্রে আমি রেফারেন্সের মাধ্যমে একটি ইন্টারফেসটি পাস করতে চাই (যেসব ক্ষেত্রে NULL গ্রহণযোগ্য নয়), এবং এইরূপে কোনও অনি-অপশন এড়াতে চাই বা সংকলনটি আরও বড়।
প্যারাসেবল

যেহেতু অ্যাসাইনমেন্ট-অপারেটরকে কখনই ডাকা উচিত নয়, আপনি কেন এটি সংজ্ঞা দেন? একপাশে হিসাবে, কেন এটি না private? এছাড়াও, আপনি ডিফল্ট- এবং অনুলিপি-কর্টোর সাথে ডিল করতে চাইতে পারেন।
উত্সাহক

5

আমি কি ভৌতিক ...

  • ইন্টারফেসে স্লাইসিংয়ের বিরুদ্ধে কোডটি সুরক্ষিত রাখতে আমি কী অসম্পূর্ণ? (আমি বিশ্বাস করি আমি নই, তবে কেউ কখনও জানে না ...)

এটি কি ঝুঁকি ব্যবস্থাপনার সমস্যা নয়?

  • আপনি কি ভয় করেন যে কাটা কাটা সম্পর্কিত একটি বাগ প্রবর্তিত হওয়ার সম্ভাবনা রয়েছে?
  • আপনি কি মনে করেন যে এটি অলক্ষিত হয়ে যায় এবং অপ্রাপ্যযোগ্য বাগগুলিকে উস্কে দিতে পারে?
  • কাটা কাটা এড়াতে আপনি কতটা যেতে ইচ্ছুক?

সেরা সমাধান

  • উপরেরগুলির মধ্যে সেরা সমাধানটি কী?

আপনার দ্বিতীয় সমাধান ("এগুলি সুরক্ষিত করুন") দেখতে দুর্দান্ত দেখাচ্ছে তবে মনে রাখবেন যে আমি কোনও সি ++ বিশেষজ্ঞ নই।
কমপক্ষে, অবৈধ ব্যবহারগুলি সঠিকভাবে আমার সংকলক (জি ++) দ্বারা ভুল হিসাবে প্রতিবেদন করেছে বলে মনে হচ্ছে।

এখন, আপনার কি ম্যাক্রো দরকার? আমি "হ্যাঁ" বলব, কারণ আপনি যে গাইডলাইনটি লিখছেন তার উদ্দেশ্য কী তা আপনি বলতে না পারলেও, আমি অনুমান করি এটি হ'ল আপনার পণ্যের কোডটিতে একটি বিশেষ সেট সেরা প্রয়োগ করা।

সেই লক্ষ্যে, লোকেরা কার্যকরভাবে প্যাটার্নটি প্রয়োগ করে যখন ম্যাক্রো সনাক্ত করতে সহায়তা করতে পারে: কমিটের একটি প্রাথমিক ফিল্টার আপনাকে ম্যাক্রো ব্যবহার করা হয়েছিল কিনা তা বলতে পারে:

  • যদি ব্যবহার করা হয়, তবে প্যাটার্নটি সম্ভবত প্রয়োগ হওয়ার সম্ভাবনা রয়েছে এবং আরও গুরুত্বপূর্ণভাবে সঠিকভাবে প্রয়োগ করা হয়েছে (কেবল কোনও protectedকীওয়ার্ড রয়েছে কিনা তা পরীক্ষা করে দেখুন ),
  • যদি ব্যবহার না করা হয় তবে আপনি কেন এটি হয়নি তা খতিয়ে দেখার চেষ্টা করতে পারেন।

ম্যাক্রোগুলিহীন, আপনাকে নিদর্শনটি প্রয়োজনীয় এবং সমস্ত ক্ষেত্রে কার্যকরভাবে প্রয়োগ করা হয়েছে কিনা তা খতিয়ে দেখতে হবে।

আরও ভাল সমাধান

  • এর চেয়ে ভাল সমাধান আর কি আছে?

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

উদাহরণস্বরূপ, একটি অনুশীলনের শিরোনাম হতে পারে " সি ++ এ নিরাপদ ইন্টারফেসের প্যাটার্নটি কী ?"

সুতরাং, আপনার সেরা পদক্ষেপটি হ'ল সিসিংয়ের সময় কী ঘটছে তা আপনার সি ++ বিকাশকারীরা তা নিশ্চিত করে to আমি নিশ্চিত যে তারা যদি তা করে তবে আপনারা যেমন ভীতি চান তেমন কোডে তারা ততটা ভুল করবে না, এমনকি সেই নির্দিষ্ট রীতিটি আনুষ্ঠানিকভাবে প্রয়োগ না করে (তবে আপনি এখনও এটি প্রয়োগ করতে পারেন, সংকলক সতর্কতাগুলি ভাল)।

সংকলক সম্পর্কে

তুমি বলো :

এই পণ্যটির জন্য সংকলকগুলির পছন্দে আমার কোনও শক্তি নেই,

প্রায়শই লোকেরা বলবে "আমার [এক্স] করার অধিকার নেই" " , " আমার [ওয়াই] করা উচিত নয় ... " , ... কারণ তারা মনে করেন এটি সম্ভব নয়, কারণ তারা না চেষ্টা বা জিজ্ঞাসা।

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

সংকলকটি বনাম রাখার ব্যয়ের মূল্যায়ন করার চেষ্টা করুন another অন্যটি ব্যবহারের জন্য ব্যয়:

  1. বর্তমান সংকলক আপনাকে এমন কী এনেছে যা অন্য কেউ পারে না?
  2. আপনার পণ্য কোড সহজেই অন্য সংকলক ব্যবহার করে সংকলনযোগ্য? না কেন ?

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


Am I paranoid...: "আপনার ইন্টারফেসগুলি সঠিকভাবে ব্যবহার করতে সহজ করুন এবং ভুলভাবে ব্যবহার করা শক্ত করুন"। আমি যখন সেই নির্দিষ্ট নীতিটি স্বাদ দিয়েছি যখন কেউ আমার স্থির পদ্ধতিটি ভুল করে ভুলভাবে ব্যবহার করে বলেছিল reported উত্পন্ন ত্রুটিটি সম্পর্কযুক্ত বলে মনে হয়েছিল এবং উত্সটি খুঁজে পেতে ইঞ্জিনিয়ারের একাধিক ঘন্টা সময় লেগেছিল। এই "ইন্টারফেস ত্রুটি" অন্যকে একটি ইন্টারফেস রেফারেন্স নির্ধারণের সাথে সমান। সুতরাং, হ্যাঁ, আমি এ জাতীয় ত্রুটি এড়াতে চাই। এছাড়াও, সি ++ তে, সংকলনের সময় দর্শনের পক্ষে যতটা সম্ভব ধরা যায় এবং ভাষা আমাদের সেই শক্তি দেয়, তাই আমরা এটি নিয়ে চলি।
প্যারাসেবল

Best solution: আমি রাজী. । । Better solution: এটি একটি দুর্দান্ত উত্তর। আমি এটি নিয়ে কাজ করব ... এখন সম্পর্কে Pure virtual classes: এটি কি? একটি সি ++ বিমূর্ত ইন্টারফেস? (রাষ্ট্রবিহীন শ্রেণি এবং কেবল খাঁটি ভার্চুয়াল পদ্ধতি?)। এই "খাঁটি ভার্চুয়াল ক্লাস" কীভাবে আমাকে কাটা থেকে রক্ষা করেছে? (খাঁটি ভার্চুয়াল পদ্ধতিগুলি ইনস্ট্যান্টেশনকে সংকলন করে না, তবে অনুলিপি-অ্যাসাইনমেন্টটি দেবে, এবং স্থানান্তরণ অ্যাসাইনমেন্টটি খুব আইআইআরসিও করবে)।
প্যারাসেবল

About the compiler: আমরা সম্মত হই, তবে আমাদের সংকলকগণ আমার দায়িত্বের বাইরে নয় (এমন নয় যে এটি আমাকে ছদ্মবেশী মন্তব্য থেকে থামায় ... :- পি ...)। আমি বিশদটি প্রকাশ করব না (আমি ইচ্ছা করতাম) তবে এটি অভ্যন্তরীণ কারণগুলির সাথে (টেস্ট স্যুটগুলির মতো) এবং বাহ্যিক কারণে (যেমন ক্লায়েন্টটি আমাদের লাইব্রেরির সাথে সংযোগ রয়েছে) এর সাথে আবদ্ধ। শেষ পর্যন্ত, সংকলক সংস্করণ পরিবর্তন (বা এমনকি এটি প্যাচিং) একটি তুচ্ছ ক্রিয়াকলাপ নয়। সাম্প্রতিক জিসিসি দিয়ে এক ভাঙা সংকলকটি একা প্রতিস্থাপন করুন।
প্যারাসেবল

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

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

2

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

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

কেন আপনার ব্যবহারকারীর কাছে উত্তরাধিকার প্রকাশের বিষয়টি খারাপ এবং কীভাবে মুছে ফেলা যায় তা শন প্যারেন্টের দ্বারা এই উপস্থাপনাগুলি কী তা ঠিক করতে সহায়তা করতে পারে তার একটি দুর্দান্ত ব্যাখ্যার জন্য:

উত্তরাধিকার হ'ল দুষ্টের বেস ক্লাস (সংক্ষিপ্ত সংস্করণ)

মূল্য শব্দার্থবিজ্ঞান এবং ধারণাগুলি-ভিত্তিক পলিমারফিজম (দীর্ঘ সংস্করণ; অনুসরণ করা সহজ, তবে শব্দ দুর্দান্ত নয়)


0

আপনি ভৌতিক নন সি ++ প্রোগ্রামার হিসাবে আমার প্রথম পেশাগত কাজটি স্লাইসিং এবং ক্রাশের ফলস্বরূপ। আমি অন্যদের সম্পর্কে জানি। এটির জন্য অনেক ভাল সমাধান নেই।

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

যদি আপনার প্রোগ্রামাররা কমান্ড লাইন ব্যবহার করে থাকে, তবে কোড তৈরি করতে NewMyCompanyInterface স্ক্রিপ্ট তৈরি করতে আপনার কাছে যা স্ক্রিপ্টিং ভাষা উপলব্ধ তা ব্যবহার করুন।

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

ম্যাক্রোস এবং অন্যান্য মেটা-প্রোগ্রামিং পদ্ধতিগুলি যা ঘটছে তা হতাশ করে এবং নতুন প্রোগ্রামাররা 'পর্দার আড়ালে' কী ঘটছে তা শিখেনি। যখন তাদের প্যাটার্নটি ভাঙতে হবে, তারা আগের মতোই হারিয়ে গেছে lost

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