সুস্পষ্ট বনাম সুস্পষ্ট ইন্টারফেস


9

আমি মনে করি আমি সংকলন-সময় পলিমারফিজম এবং রান-টাইম পলিমারফিজমের আসল সীমাবদ্ধতাগুলি বুঝতে পারি। তবে সুস্পষ্ট ইন্টারফেসের মধ্যে ধারণাগত পার্থক্যগুলি কী (রান-টাইম পলিমারফিজম। অর্থাৎ ভার্চুয়াল ফাংশন এবং পয়েন্টার / রেফারেন্স) এবং অন্তর্নিহিত ইন্টারফেস (সংকলন-কাল পলিমারফিজম। অর্থাৎ টেম্পলেট)

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

এই সম্পর্কে কোন চিন্তা?

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

কিছু সম্পর্কিত পোস্ট:


এই প্রশ্নটি আরও নিবিড় করার জন্য এখানে একটি উদাহরণ দেওয়া হয়েছে:

অন্তর্ভুক্ত ইন্টারফেস:

class Class1
{
public:
  void interfaceFunc();
  void otherFunc1();
};

class Class2
{
public:
  void interfaceFunc();
  void otherFunc2();
};

template <typename T>
class UseClass
{
public:
  void run(T & obj)
  {
    obj.interfaceFunc();
  }
};

সুস্পষ্ট ইন্টারফেস:

class InterfaceClass
{
public:
  virtual void interfaceFunc() = 0;
};

class Class1 : public InterfaceClass
{
public:
  virtual void interfaceFunc();
  void otherFunc1();
};

class Class2 : public InterfaceClass
{
public:
  virtual void interfaceFunc();
  void otherFunc2();
};

class UseClass
{
public:
  void run(InterfaceClass & obj)
  {
    obj.interfaceFunc();
  }
};

আরও গভীরতর, কংক্রিটের উদাহরণ:

কিছু সি ++ টি সমস্যার সাথে সমাধান করা যেতে পারে:

  1. একটি টেম্প্লেটেড ক্লাস যার টেম্পলেট প্রকার একটি অন্তর্নিহিত ইন্টারফেস সরবরাহ করে
  2. একটি অ-টেম্প্লেটেড ক্লাস যা একটি বেস-ক্লাস পয়েন্টার নেয় যা একটি স্পষ্ট ইন্টারফেস সরবরাহ করে

কোড যা পরিবর্তন হয় না:

class CoolClass
{
public:
  virtual void doSomethingCool() = 0;
  virtual void worthless() = 0;
};

class CoolA : public CoolClass
{
public:
  virtual void doSomethingCool()
  { /* Do cool stuff that an A would do */ }

  virtual void worthless()
  { /* Worthless, but must be implemented */ }
};

class CoolB : public CoolClass
{
public:
  virtual void doSomethingCool()
  { /* Do cool stuff that a B would do */ }

  virtual void worthless()
  { /* Worthless, but must be implemented */ }
};

মামলা 1 । একটি অ-টেম্প্লেটেড ক্লাস যা একটি বেস-ক্লাস পয়েন্টার নেয় যা একটি স্পষ্ট ইন্টারফেস সরবরাহ করে:

class CoolClassUser
{
public:  
  void useCoolClass(CoolClass * coolClass)
  { coolClass.doSomethingCool(); }
};

int main()
{
  CoolA * c1 = new CoolClass;
  CoolB * c2 = new CoolClass;

  CoolClassUser user;
  user.useCoolClass(c1);
  user.useCoolClass(c2);

  return 0;
}

মামলা 2 । একটি টেম্পলেটেড ক্লাস যার টেম্পলেট প্রকারটি একটি অন্তর্নিহিত ইন্টারফেস সরবরাহ করে:

template <typename T>
class CoolClassUser
{
public:  
  void useCoolClass(T * coolClass)
  { coolClass->doSomethingCool(); }
};

int main()
{
  CoolA * c1 = new CoolClass;
  CoolB * c2 = new CoolClass;

  CoolClassUser<CoolClass> user;
  user.useCoolClass(c1);
  user.useCoolClass(c2);

  return 0;
}

মামলা 3 । একটি টেম্প্লেটেড ক্লাস যার টেম্পলেট প্রকার একটি অন্তর্নিহিত ইন্টারফেস সরবরাহ করে (এই সময় থেকে প্রাপ্ত নয় CoolClass:

class RandomClass
{
public:
  void doSomethingCool()
  { /* Do cool stuff that a RandomClass would do */ }

  // I don't have to implement worthless()! Na na na na na!
}


template <typename T>
class CoolClassUser
{
public:  
  void useCoolClass(T * coolClass)
  { coolClass->doSomethingCool(); }
};

int main()
{
  RandomClass * c1 = new RandomClass;
  RandomClass * c2 = new RandomClass;

  CoolClassUser<RandomClass> user;
  user.useCoolClass(c1);
  user.useCoolClass(c2);

  return 0;
}

কেস 1 এর প্রয়োজন হয় যে অবজেক্টটি useCoolClass()শিশুটিকে CoolClass(এবং বাস্তবায়ন করা worthless()) হতে দেওয়া হবে। অন্যদিকে, কেস 2 এবং 3, কোনওdoSomethingCool() ফাংশন রয়েছে এমন কোনও শ্রেণিতে নেবে ।

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


সম্ভবত আমি কিছু মিস করছি, তবে আপনার প্রথম অনুচ্ছেদে ইতিমধ্যে সংজ্ঞা অনুসারে গুরুত্বপূর্ণ পার্থক্যটি কি তা নয়, যা স্পষ্টত ইন্টারফেসগুলি রান-টাইম পলিমারফিজম হয়, তবে অন্তর্নিহিত ইন্টারফেসগুলি সংকলন-কাল বহুবৈজ্ঞান হয়?
রবার্ট হার্ভে

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

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

উত্তর:


8

আপনি ইতিমধ্যে গুরুত্বপূর্ণ পয়েন্টটি সংজ্ঞায়িত করেছেন - একটি রান-টাইম এবং অন্যটি সংকলন-সময় । আপনার প্রয়োজনীয় আসল তথ্য হ'ল এই পছন্দটির ব্যর্থতা।

Compiletime:

  • প্রো: কম্পাইল-টাইম ইন্টারফেসগুলি রান-টাইমগুলির চেয়ে অনেক বেশি দানাদার। এর মাধ্যমে, আমি যা বলতে চাইছি তা হ'ল আপনি যেমন কল করেন তেমন কেবলমাত্র একটি একক ফাংশনের প্রয়োজনীয়তা বা ফাংশনের একটি সেট ব্যবহার করতে পারেন। আপনাকে সর্বদা পুরো ইন্টারফেসটি করতে হবে না। প্রয়োজনীয়তাগুলি কেবল এবং ঠিক আপনার যা প্রয়োজন are
  • প্রো: সিআরটিপির মতো কৌশলগুলির অর্থ আপনি অপারেটরগুলির মতো জিনিসগুলির ডিফল্ট রূপায়ণে অন্তর্নির্মিত ইন্টারফেস ব্যবহার করতে পারেন। রান-টাইম উত্তরাধিকার নিয়ে আপনি কখনই এ জাতীয় কাজটি করতে পারেন নি।
  • প্রো: অন্তর্নির্মিত ইন্টারফেসগুলি রান-টাইম ইন্টারফেসের চেয়ে "উত্তরাধিকারী" রচনা করা এবং গুণ করা আরও সহজ, এবং কোনও ধরণের বাইনারি বিধিনিষেধ আরোপ করবেন না - উদাহরণস্বরূপ, পিওডি ক্লাসগুলি অন্তর্নিহিত ইন্টারফেস ব্যবহার করতে পারে। virtualঅন্তর্নিহিত ইন্টারফেস সহ উত্তরাধিকারের বা অন্য শেননিগানের কোনও দরকার নেই a একটি বড় সুবিধা।
  • প্রো: সংকলক সংকলন-সময় ইন্টারফেসের জন্য আরও অনুকূলিতকরণ করতে পারে। এছাড়াও, অতিরিক্ত ধরণের সুরক্ষা নিরাপদ কোড তৈরি করে।
  • প্রো: রান-টাইম ইন্টারফেসের জন্য মূল্য টাইপ করা অসম্ভব, কারণ আপনি চূড়ান্ত বস্তুর আকার বা প্রান্তিককরণ জানেন না। এর অর্থ হ'ল মান টাইপিংয়ের যে কোনও ক্ষেত্রে / বেনিফিটগুলির প্রয়োজন টেমপ্লেটগুলি থেকে বড় সুবিধা অর্জন করে।
  • কন: টেমপ্লেটগুলি সংকলন এবং ব্যবহারের জন্য একটি দুশ্চরিত্রা, এবং সেগুলি স্পষ্টভাবে সংকলকগুলির মধ্যে পোর্টিং করা যেতে পারে
  • কন: টেমপ্লেটগুলি রান-টাইমে (স্পষ্টতই) লোড করা যায় না, সুতরাং গতিশীল ডেটা স্ট্রাকচারের প্রকাশের তাদের সীমা থাকে have

তারিখ:

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

আপেক্ষিক তালিকা দেওয়া, যদি আপনার রান-টাইম উত্তরাধিকারের কোনও নির্দিষ্ট সুবিধা প্রয়োজন না হয় তবে এটি ব্যবহার করবেন না। এটি ধীর, কম নমনীয় এবং টেমপ্লেটগুলির চেয়ে কম নিরাপদ।

সম্পাদনা: এটি লক্ষণীয় যে সি ++ তে বিশেষত রান-টাইম পলিমারফিজম ব্যতীত উত্তরাধিকারের জন্য অন্যান্য ব্যবহার রয়েছে । উদাহরণস্বরূপ, আপনি টাইপডেফগুলি উত্তরাধিকারী হতে পারেন, বা এটি ট্যাগিংয়ের জন্য ব্যবহার করতে পারেন, বা সিআরটিপি ব্যবহার করতে পারেন। শেষ পর্যন্ত, যদিও এই কৌশলগুলি (এবং অন্যান্য) সত্যই "সংকলন-সময়" এর আওতায় পড়ে, যদিও সেগুলি প্রয়োগ করে প্রয়োগ করা হয় class X : public Y


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

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

1
@ ক্রিসমরিস: না, আমি চাই না। আমার যদি কেবল এক্স দরকার হয় তবে এটি এনক্যাপসুলেশনের প্রাথমিক মৌলিক নীতিগুলির মধ্যে একটি যা আমার কাছে কেবল এক্স সম্পর্কে জিজ্ঞাসা করা এবং যত্ন করা উচিত Also এছাড়াও, এটি টাইপ তথ্য হারাতে পারে না। আপনি উদাহরণস্বরূপ, স্ট্যাক এ জাতীয় ধরণের একটি অবজেক্ট বরাদ্দ করতে পারবেন না। আপনি কোনও টেম্পলেটটি সত্য ধরণের দিয়ে ইনস্ট্যান্ট করতে পারবেন না। আপনি তাদের উপর টেম্প্লেটেড সদস্য ফাংশনগুলি কল করতে পারবেন না।
ডেড এমএমজি

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

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