সি ++ তে একটি টেম্পলেট শ্রেণি থেকে উত্তরাধিকার


106

ধরা যাক আমাদের একটি টেম্পলেট শ্রেণি রয়েছে Area, যার একটি সদস্য ভেরিয়েবল T area, একটি T getArea()এবং void setArea(T)সদস্য ফাংশন রয়েছে।

আমি Areaটাইপ করে একটি নির্দিষ্ট ধরণের একটি অবজেক্ট তৈরি করতে পারি Area<int>

এখন আমার ক্লাসটি ক্লাসের Rectangleউত্তরাধিকার সূত্রে প্রাপ্ত Area। যেহেতু Rectangleনিজেই কোনও টেম্পলেট নয়, তাই টাইপ করতে পারি না Rectangle<int>

আমি কীভাবে বস্তুর Areaজন্য উত্তরাধিকার সূত্রে Rectangleবিশেষত করব?

সম্পাদনা: দুঃখিত, আমি স্পষ্ট করে বলতে ভুলে গেছি - আমার প্রশ্নগুলি হল এরিয়াটিকে বিশেষত্ব না দিয়ে উত্তরাধিকারী করা সম্ভব কিনা, সুতরাং এটি অঞ্চল হিসাবে স্থান হিসাবে প্রাপ্ত হয় না তবে অঞ্চল আয়তক্ষেত্রটি ধরণের বিশেষায়িত করতে পারে।


3
এটি শ্রেণীর টেম্পলেট , কারণ এটি এমন একটি টেম্পলেট যা থেকে শ্রেণিগুলি উত্পন্ন হয়।
এসবিআই

1
@ এসবিআই আমি এখানে শিখা যুদ্ধ শুরু করার ইচ্ছা করি না, তবে যদি বর্জন স্ট্রস্ট্রপ শ্রেণিবদ্ধ টেম্পলেট এবং টেম্পলেট শ্রেণীর মধ্যে পার্থক্য তৈরি না করে ( সি ++ প্রোগ্রামিং ভাষা , চতুর্থ সংস্করণ, বিভাগ 23.2.1 দেখুন), তবে আপনার উচিত হবে না হয় না।
মাইকেল ওয়ার্নার

@ মিশেল ওয়ার্নারকে আমি মনে করি তাকে আলাদা করে দেখছি making এটি ছিল উনিনেটে, যদিও, 90 এর দশকে। তখন থেকে তিনি হাল ছেড়ে দিয়েছেন। (অথবা হতে পারে সে একটি তাত্ক্ষণিক শ্রেণীর টেম্পলেটটিকে একটি টেম্পলেট শ্রেণি হিসাবে উল্লেখ করে?)
এসবিআই

উত্তর:


244

টেমপ্লেটগুলি বোঝার জন্য, পরিভাষাটি সোজা পাওয়া খুব সুবিধার কারণ কারণ আপনি তাদের সম্পর্কে কথা বলার উপায় সেগুলি সম্পর্কে চিন্তাভাবনার উপায় নির্ধারণ করে।

বিশেষত, Areaকোনও টেম্পলেট শ্রেণি নয়, একটি শ্রেণিবদ্ধ টেম্পলেট। এটি, এটি এমন একটি টেম্পলেট যা থেকে ক্লাস তৈরি করা যায়। Area<int>যেমন একটি বর্গ (এটা হয় না একটি বস্তু, কিন্তু অবশ্যই আপনি একই উপায়ে আপনি অন্য কোন ক্লাস থেকে বস্তু তৈরি করতে পারেন যে বর্গ থেকে একটি বস্তু তৈরি করতে পারেন)। এরকম আরও একটি ক্লাস হবে Area<char>। মনে রাখবেন যে সেগুলি সম্পূর্ণ আলাদা শ্রেণি, যা একই শ্রেণীর টেম্পলেট থেকে উত্পন্ন হয়েছিল তা বাদে এগুলির কিছুই সাধারণ নেই।

যেহেতু Areaকোনও ক্লাস নয়, আপনি Rectangleএটি থেকে ক্লাসটি অর্জন করতে পারবেন না । আপনি কেবলমাত্র অন্য শ্রেণীর (বা তাদের বেশ কয়েকটি) ক্লাস পেতে পারেন। যেহেতু Area<int>একটি শ্রেণি, আপনি উদাহরণস্বরূপ, Rectangleএটি থেকে প্রাপ্ত করতে পারেন:

class Rectangle:
  public Area<int>
{
  // ...
};

যেহেতু Area<int>এবং Area<char>বিভিন্ন শ্রেণি, আপনি এমনকি একই সময়ে উভয় থেকে উদ্ভূত করতে পারেন (তবে তাদের সদস্যদের অ্যাক্সেস করার সময়, আপনাকে দ্ব্যর্থহীনতার মোকাবেলা করতে হবে):

class Rectangle:
  public Area<int>,
  public Area<char>
{
  // ...
};

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

আপনি যা করতে পারেন তা হ'ল Rectangleএকটি টেম্পলেটও তৈরি করা। যদি লিখি

template<typename T> class Rectangle:
  public Area<T>
{
  // ...
};

আপনার কাছে এমন একটি টেম্পলেট Rectangleরয়েছে যা থেকে আপনি একটি ক্লাস পেতে পারেন Rectangle<int>যা থেকে এসেছে Area<int>এবং একটি আলাদা ক্লাস Rectangle<char>যা থেকে এসেছে Area<char>

এটি এমন হতে পারে যে আপনি একটি একক প্রকার রাখতে চান Rectangleযাতে আপনি সমস্ত ধরণের Rectangleএকই ফাংশনে (যা নিজেই অঞ্চল প্রকারটি জানার প্রয়োজন হয় না) পাস করতে পারেন । যেহেতু Rectangle<T>টেমপ্লেট ইনস্ট্যান্ট করে উত্পন্ন ক্লাসগুলি Rectangleএকে অপরের থেকে আনুষ্ঠানিকভাবে স্বতন্ত্র, এটি সেভাবে কাজ করে না। তবে আপনি এখানে একাধিক উত্তরাধিকার ব্যবহার করতে পারেন:

class Rectangle // not inheriting from any Area type
{
  // Area independent interface
};

template<typename T> class SpecificRectangle:
  public Rectangle,
  public Area<T>
{
  // Area dependent stuff
};

void foo(Rectangle&); // A function which works with generic rectangles

int main()
{
  SpecificRectangle<int> intrect;
  foo(intrect);

  SpecificRectangle<char> charrect;
  foo(charrect);
}

যদি আপনার জেনেরিকটি জেনেরিক Rectangleথেকে উদ্ভূত হয় তবে Areaআপনার সাথে একই কৌশলটি করতে পারেন Area:

class Area
{
  // generic Area interface
};

class Rectangle:
  public virtual Area // virtual because of "diamond inheritance"
{
  // generic rectangle interface
};

template<typename T> class SpecificArea:
  public virtual Area
{
  // specific implementation of Area for type T
};

template<typename T> class SpecificRectangle:
  public Rectangle, // maybe this should be virtual as well, in case the hierarchy is extended later
  public SpecificArea<T> // no virtual inheritance needed here
{
  // specific implementation of Rectangle for type T
};

দ্রষ্টব্য: একটি টেম্পলেট ধরণের পরামিতি কোনও বস্তুর শ্রেণীর অংশ যা সেই শ্রেণীর টেম্পলেটটি ইনস্ট্যান্ট করে। অন্য কথায়, এটি শ্রেণীর কোনও উপাদান নয়, এটি ধরণের অংশ।
নিকস

21

আপনি কি থেকে প্রাপ্ত করার চেষ্টা করছেন Area<int>? কোন ক্ষেত্রে আপনি এটি করেন:

class Rectangle : public Area<int>
{
    // ...
};

সম্পাদনা: স্পষ্টকরণের পরে, আপনি সম্ভবত Rectangleএকটি টেম্পলেট তৈরি করার চেষ্টা করছেন বলে মনে হচ্ছে , নিম্নলিখিত ক্ষেত্রে কাজ করা উচিত:

template <typename T>
class Rectangle : public Area<T>
{
    // ...
};


8

আয়তক্ষেত্রটিকে একটি টেম্পলেট তৈরি করুন এবং টাইপনেমটি এরিয়াতে পাস করুন:

template <typename T>
class Rectangle : public Area<T>
{

};

6

Rectangleএকটি টেমপ্লেট হতে হবে, অন্যথায় এটি কেবল এক প্রকারের । এটি বেস-টেম্পলেট হতে পারে না যদিও এর ভিত্তিটি ম্যাজিকালি। (এর বেসটি কোনও টেম্পলেট ইনস্ট্যান্টেশন হতে পারে , যদিও আপনি টেমপ্লেট হিসাবে বেসের কার্যকারিতা বজায় রাখতে চান বলে মনে হয় ))


3
#include<iostream>

using namespace std;

template<class t> 
class base {
protected:
    t a;
public:
    base(t aa){
        a = aa;
        cout<<"base "<<a<<endl;
    }
};

template <class t> 
class derived: public base<t>{
    public:
        derived(t a): base<t>(a) {
        }
        //Here is the method in derived class 
    void sampleMethod() {
        cout<<"In sample Method"<<endl;
    }
};

int main() {
    derived<int> q(1);
    // calling the methods
    q.sampleMethod();
}

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

6
প্রথমত, এটি একটি সত্যই পুরানো প্রশ্ন যার ইতিমধ্যে একটি দুর্দান্ত উত্তর রয়েছে। দ্বিতীয়ত, দয়া করে উত্তর (এবং প্রশ্নগুলি) এড়িয়ে চলুন যা কেবল কোড। পাশাপাশি বিস্তারিত ব্যাখ্যা অন্তর্ভুক্ত করা দরকারী।
মার্কমান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.