আমি মনে করি আমি সংকলন-সময় পলিমারফিজম এবং রান-টাইম পলিমারফিজমের আসল সীমাবদ্ধতাগুলি বুঝতে পারি। তবে সুস্পষ্ট ইন্টারফেসের মধ্যে ধারণাগত পার্থক্যগুলি কী (রান-টাইম পলিমারফিজম। অর্থাৎ ভার্চুয়াল ফাংশন এবং পয়েন্টার / রেফারেন্স) এবং অন্তর্নিহিত ইন্টারফেস (সংকলন-কাল পলিমারফিজম। অর্থাৎ টেম্পলেট) ।
আমার ধারণা হ'ল দুটি স্পষ্টত যা একই স্পষ্ট ইন্টারফেসটি দেয় সেগুলি অবশ্যই একই ধরণের অবজেক্ট (বা একটি সাধারণ পূর্বপুরুষ থাকতে হবে) হতে পারে, একইরকম অন্তর্নিহিত ইন্টারফেসের প্রস্তাব দেয় এমন দুটি বস্তু একই ধরণের অবজেক্টের প্রয়োজন হবে না এবং, অন্তর্নিহিত ব্যতীত ইন্টারফেস যে তারা উভয় অফার, বেশ ভিন্ন কার্যকারিতা থাকতে পারে।
এই সম্পর্কে কোন চিন্তা?
এবং যদি দুটি বস্তু একই অন্তর্নিহিত ইন্টারফেসের প্রস্তাব দেয় তবে কী কারণগুলি (গতিশীল প্রেরণ ডাব্লু / ভার্চুয়াল ফাংশন অনুসন্ধানের টেবিল ইত্যাদির প্রয়োজন না পড়ার প্রযুক্তিগত সুবিধার পাশে) এই অবজেক্টগুলিকে বেস ইন্টারফেসের উত্তরাধিকারসূত্রে না পাওয়ার জন্য রয়েছে যা এই ইন্টারফেসটিকে ঘোষণা করে, সুতরাং এটি একটি স্পষ্ট ইন্টারফেস তৈরি? এটি বলার আরেকটি উপায়: আপনি কি আমাকে এমন একটি মামলা দিতে পারেন যেখানে দুটি অবজেক্ট একই রকম অন্তর্নিহিত ইন্টারফেসের (এবং সেইজন্য নমুনা টেম্পলেট শ্রেণীর ধরণের হিসাবে ব্যবহার করা যেতে পারে) এমন কোনও বেস ক্লাসের উত্তরাধিকারী না হওয়া উচিত যা সেই ইন্টারফেসটিকে স্পষ্ট করে তোলে?
কিছু সম্পর্কিত পোস্ট:
- https://stackoverflow.com/a/7264550/635125
- https://stackoverflow.com/a/7264689/635125
- https://stackoverflow.com/a/8009872/635125
এই প্রশ্নটি আরও নিবিড় করার জন্য এখানে একটি উদাহরণ দেওয়া হয়েছে:
অন্তর্ভুক্ত ইন্টারফেস:
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();
}
};
আরও গভীরতর, কংক্রিটের উদাহরণ:
কিছু সি ++ টি সমস্যার সাথে সমাধান করা যেতে পারে:
- একটি টেম্প্লেটেড ক্লাস যার টেম্পলেট প্রকার একটি অন্তর্নিহিত ইন্টারফেস সরবরাহ করে
- একটি অ-টেম্প্লেটেড ক্লাস যা একটি বেস-ক্লাস পয়েন্টার নেয় যা একটি স্পষ্ট ইন্টারফেস সরবরাহ করে
কোড যা পরিবর্তন হয় না:
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()
ফাংশন রয়েছে তা রোল করতে চান কিনা তা আমি অনুমান করতে পারি না ।