সি ++ এ "সুপার" ব্যবহার করা হচ্ছে


203

আমার কোডিংয়ের শৈলীতে নিম্নলিখিত আইডিয়ামটি অন্তর্ভুক্ত রয়েছে:

class Derived : public Base
{
   public :
      typedef Base super; // note that it could be hidden in
                          // protected/private section, instead

      // Etc.
} ;

এটি আমাকে বেসের একটি উপন্যাস হিসাবে "সুপার" ব্যবহার করতে সক্ষম করে, উদাহরণস্বরূপ, নির্মাণকারীগুলিতে:

Derived(int i, int j)
   : super(i), J(j)
{
}

বা এমনকি তার ওভাররাইড সংস্করণে বেস শ্রেণি থেকে পদ্ধতিটি কল করার সময়:

void Derived::foo()
{
   super::foo() ;

   // ... And then, do something else
}

এটি এমনকি শৃঙ্খলাবদ্ধ হতে পারে (যদিও এর জন্য আমার এখনও সন্ধান পাওয়া যায়):

class DerivedDerived : public Derived
{
   public :
      typedef Derived super; // note that it could be hidden in
                             // protected/private section, instead

      // Etc.
} ;

void DerivedDerived::bar()
{
   super::bar() ; // will call Derived::bar
   super::super::bar ; // will call Base::bar

   // ... And then, do something else
}

যাইহোক, আমি "টাইপিডেফ সুপার" এর ব্যবহারটি খুব দরকারী মনে করি, উদাহরণস্বরূপ, যখন বেস হয় ভার্বোস এবং / অথবা টেম্প্ল্যাটেড হয়।

আসল বিষয়টি হ'ল সুপার জাভাতে প্রয়োগ করা হয়, পাশাপাশি সি # তে (যেখানে আমি ভুল না হলে এটি "বেস" বলা হয়)। তবে সি ++ এর এই কীওয়ার্ডের অভাব রয়েছে।

সুতরাং, আমার প্রশ্নগুলি:

  • টাইপএফের ব্যবহারটি কি সুপার / সাধারণ / বিরল / আপনি যে কোডটি ব্যবহার করেন তার মধ্যে কখনই দেখা যায় না?
  • টাইপেফ সুপার ওকের এই ব্যবহারটি (যেমন আপনি এটি ব্যবহার না করার জন্য দৃ strong় বা এত শক্ত কারণ দেখেন না)?
  • "সুপার" ভাল জিনিস হওয়া উচিত, এটি কি কিছুটা সি ++ তে প্রমিত করা উচিত, নাকি টাইপডিফের মাধ্যমে এটি ইতিমধ্যে যথেষ্ট?

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

সম্পাদনা 2: এখন, "সুপার" ব্যাপকভাবে ব্যবহার করার কয়েক মাস পরে, আমি রডির দৃষ্টিভঙ্গির সাথে আন্তরিকভাবে একমত: "সুপার" ব্যক্তিগত হওয়া উচিত। আমি তার উত্তর দুটি বার upvote হবে, কিন্তু আমি অনুমান করতে পারি না।


অসাধারণ! ঠিক আমি খুঁজছেন ছিল কি. এখন অবধি আমার এই কৌশলটি ব্যবহার করার দরকার পড়বেন না। আমার ক্রস-প্ল্যাটফর্ম কোডের জন্য দুর্দান্ত সমাধান।
অ্যালানকলে

6
আমার কাছে superদেখতে দেখতে Javaএটি খারাপ কিছু নয়, তবে ... তবে C++একাধিক উত্তরাধিকারকে সমর্থন করে।
ST3

2
@ ব্যবহারকারী 2623967: ঠিক। সাধারণ উত্তরাধিকারের ক্ষেত্রে, একটি "সুপার" যথেষ্ট। এখন, যদি আপনার একাধিক উত্তরাধিকার থাকে তবে "সুপারএ", "সুপারবি" ইত্যাদি একটি ভাল সমাধান: আপনি কোনও একটি বাস্তবায়ন থেকে অন্য পদ্ধতিটি কল করতে চান, তাই আপনার কী প্রয়োগায়ন চান তা অবশ্যই আপনাকে জানান। "সুপার" -র মতো টাইপইডেফ ব্যবহার আপনাকে একটি সহজ অ্যাক্সেসযোগ্য / লিখনযোগ্য নাম সরবরাহ করতে সক্ষম করে (পরিবর্তে বলি, MyFirstBase<MyString, MyStruct<MyData, MyValue>>সব জায়গায় লেখার জন্য )
পায়েসারবাল

নোট করুন যে কোনও টেম্পলেট থেকে উত্তরাধিকার সূত্রে যখন তা উল্লেখ করার সময় আপনার টেম্পলেট যুক্তিগুলি অন্তর্ভুক্ত করার দরকার নেই। উদাহরণস্বরূপ: template <class baz> struct Foo {...void bar() {...} ...}; struct Foo2: Foo<AnnoyinglyLongListOfArguments> { void bar2() { ... Foo::bar(); ...} };এটি gcc 9.1 --std = c ++ 1y (c ++ 14) দিয়ে আমার সাথে কাজ করেছে।
থানাসিস পাপআউটসাইডাকিস

1
... উম, সংশোধন এটি কেবল 14 নয়, কোনও সি ++ স্ট্যান্ডার্ডে কাজ করছে বলে মনে হচ্ছে
থানাসিস পাপআউটসাইডাকিস

উত্তর:


151

সিজন + এর ডিজাইন এবং বিবর্তনে বাজনে স্ট্রস্ট্রপ উল্লেখ করেছেন যে superকোনও সিওয়ার্ড হিসাবে আইএসও সি ++ স্ট্যান্ডার্ড কমিটি প্রথমবার সি ++ স্ট্যান্ডার্ড করেছিল।

ডাগ ব্রুক এই বর্ধিতকরণের প্রস্তাব করেছিল, বেস শ্রেণিকে "উত্তরাধিকারসূত্রে" বলে calling প্রস্তাবটিতে একাধিক উত্তরাধিকারের বিষয়টি উল্লেখ করা হয়েছে এবং এতে অস্পষ্ট ব্যবহারগুলি চিহ্নিত করা হবে। এমনকি স্ট্রস্ট্রস্ট্রও দৃ was় বিশ্বাসী ছিল।

আলোচনার পরে ড্যাগ ব্রুক (হ্যাঁ, একই ব্যক্তি প্রস্তাবটি তৈরি করেছিলেন) লিখেছিলেন যে প্রস্তাবটি কার্যকর, প্রযুক্তিগতভাবে সুদৃ .় এবং বড় ত্রুটিমুক্ত ছিল এবং একাধিক উত্তরাধিকার পরিচালনা করেছিল। অন্যদিকে, বাক্সের জন্য পর্যাপ্ত পরিমাণে ঠাঁই ছিল না, এবং কমিটির উচিত একটি কাঁটাযুক্ত সমস্যা পরিচালনা করা।

মাইকেল টিম্যান দেরীতে পৌঁছেছিলেন এবং তারপরে দেখিয়েছেন যে একজন টাইপডেফড সুপার ঠিক এই কাজ করবেন, এই পোস্টটিতে জিজ্ঞাসা করা একই কৌশলটি ব্যবহার করে।

সুতরাং, না, এটি সম্ভবত প্রমিত হবে না।

আপনার যদি অনুলিপি না থাকে তবে নকশা এবং বিবর্তনটি কভারের দামের পক্ষে বেশ মূল্যবান। ব্যবহৃত অনুলিপিগুলি প্রায় 10 ডলারে থাকতে পারে।


5
ডি অ্যান্ড ই আসলেই একটি ভাল বই। তবে মনে হচ্ছে এটি পুনরায় পড়ার দরকার আছে - আমার কোনও গল্প মনে নেই।
মাইকেল বুড়

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

12
কৌশলটিতে একটি বড় ত্রুটি রয়েছে typedef: এটি ডিআরওয়াইয়ের সম্মান করে না। চারপাশের একমাত্র উপায় হ'ল ক্লাস ঘোষণার জন্য কুৎসিত ম্যাক্রো ব্যবহার করা। আপনি উত্তরাধিকারী হয়ে গেলে, বেসটি দীর্ঘ মাল্টি প্যারামিটার টেম্পলেট শ্রেণি বা আরও খারাপ হতে পারে। (উদাঃ মাল্টি ক্লাস) আপনাকে দ্বিতীয়বারের মতো আবার লিখতে হবে। অবশেষে, আমি টেমপ্লেট ঘাঁটিগুলির সাথে একটি বড় সমস্যা দেখি যার মধ্যে টেম্পলেট শ্রেণীর আর্গুমেন্ট রয়েছে। এক্ষেত্রে সুপার হ'ল একটি টেম্পলেট (এবং কোনও টেমপ্লেটের ইনস্ট্যান্সেশন নয়)। যা টাইপফিড হতে পারে না। এমনকি সি ++ 11 এও আপনার usingএই ক্ষেত্রে প্রয়োজন ।
v.oddou

105

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

class MyClass : public MyBase
{
private:  // Prevents erroneous use by other classes.
  typedef MyBase inherited;
...

নতুন ক্লাস তৈরির জন্য আমার স্ট্যান্ডার্ড 'কোড টেমপ্লেট' এ টাইপডেফ অন্তর্ভুক্ত রয়েছে, তাই আমার এটি দুর্ঘটনাক্রমে বাদ দেওয়ার খুব কম সুযোগ রয়েছে।

আমি মনে করি না যে শৃঙ্খলিত "সুপার :: সুপার" পরামর্শটি একটি ভাল ধারণা- যদি আপনি এটি করছেন তবে আপনি সম্ভবত একটি নির্দিষ্ট শ্রেণিবিন্যাসের সাথে খুব কঠোরভাবে আবদ্ধ হয়ে আছেন, এবং এটি পরিবর্তন করার ফলে জিনিসগুলি খারাপভাবে ভেঙে যাবে।


2
সুপার শৃঙ্খলাবদ্ধ হিসাবে সুপার :: সুপার হিসাবে, আমি প্রশ্নে উল্লেখ করেছি, এখনও আমি এটির একটি আকর্ষণীয় ব্যবহার খুঁজে পেতে পারি। আপাতত, আমি কেবল এটি হ্যাক হিসাবে দেখছি, তবে এটি জাভার সাথে পার্থক্যের জন্য (যদি আপনি "সুপার" চেইন করতে পারেন না) তবে এটি উল্লেখ করার মতো ছিল।
পাইরেসাল

4
আমি কয়েক মাস পরে, আপনার দৃষ্টিভঙ্গিতে রূপান্তরিত হয়েছিলাম (এবং আপনি যেমন ভুলে গিয়েছিলেন "সুপার" এর কারণে আমি একটি বাগ পেয়েছিলাম ...)। শৃঙ্খলাকৃতি সহ আপনি আপনার উত্তরে বেশ সঠিক, আমার ধারণা। ^ _ ^ ...
প্যারাসেবল

প্যারেন্ট ক্লাসের পদ্ধতিগুলি কল করতে আমি এখন এটি কীভাবে ব্যবহার করব?
এমএল স্টুডেন্ট 33

এর অর্থ কী এখানে আমাকে virtualযেমন দেখানো হয়েছে তেমন সমস্ত বেস ক্লাসের পদ্ধতিগুলি ঘোষণা করতে হবে : মার্টিনবোরডহর্স্ট.com
typedef-

36

এর সাথে একটি সমস্যা হ'ল যদি আপনি উত্পন্ন ক্লাসগুলির জন্য সুপার (পুনরায়) সংজ্ঞায়িত করতে ভুলে যান, তবে সুপারের যে কোনও কল :: কিছু ভাল করে সংকলন করবে তবে সম্ভবত পছন্দসই ফাংশনটি কল করবে না।

উদাহরণ স্বরূপ:

class Base
{
public:  virtual void foo() { ... }
};

class Derived: public Base
{
public:
    typedef Base super;
    virtual void foo()
    {
        super::foo();   // call superclass implementation

        // do other stuff
        ...
    }
};

class DerivedAgain: public Derived
{
public:
    virtual void foo()
    {
        // Call superclass function
        super::foo();    // oops, calls Base::foo() rather than Derived::foo()

        ...
    }
};

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


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

5
তবে, প্রাইভেট টাইপিডেফ মূল পোস্টে উল্লিখিত শৃঙ্খলিত ব্যবহারকে রোধ করবে।
এন্টি

1
এই সঠিক বাগটি
চালানোই

সুতরাং super1বেস এবং super2ডাইরাইভেডের জন্য ব্যবহার করবেন ? ডেরিভডগেইন দুটোই ব্যবহার করতে পারে?
এমএল স্টুডেন্ট 33

20

FWIW মাইক্রোসফ্ট তাদের সংকলকটিতে __সুপারের জন্য একটি এক্সটেনশন যুক্ত করেছে ।


এখানে কয়েকটি বিকাশকারী __সুপার ব্যবহার করার জন্য চাপ দেওয়া শুরু করেছেন। এটি "ভুল" এবং "অ-স্টানাডার্ড" বলে মনে হওয়ায় প্রথমে আমি পিছনে এসেছি। যাইহোক, আমি এটি ভালবাসা বড় হয়েছি।
আর্ডওয়ার্ক

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

15

সুপার (বা উত্তরাধিকারসূত্রে) হ'ল খুব ভাল জিনিস কারণ আপনার যদি বেস এবং উত্সর্গের মধ্যে অন্য উত্তরাধিকার স্তরটি আটকাতে হয় তবে আপনাকে কেবল দুটি জিনিস পরিবর্তন করতে হবে: ১ "ক্লাস বেস: ফু" এবং ২ টাইপডেফ

আমি যদি সঠিকভাবে স্মরণ করি তবে সি ++ স্ট্যান্ডার্ড কমিটি এর জন্য একটি কীওয়ার্ড যুক্ত করার কথা বিবেচনা করছিল ... যতক্ষণ না মাইকেল টাইম্যান এই টাইডেফ ট্রিকটি কাজ করে তা নির্দেশ না করে।

একাধিক উত্তরাধিকার হিসাবে, যেহেতু এটি প্রোগ্রামার নিয়ন্ত্রণের অধীনে আপনি যা খুশি করতে পারেন: সম্ভবত সুপার 1 এবং সুপার 2, বা যাই হোক না কেন।


13

আমি সবেমাত্র একটি বিকল্প কাজ পেয়েছি। টাইপেফ পদ্ধতির সাথে আমার একটি বড় সমস্যা রয়েছে যা আজ আমাকে বিট দেয়:

  • টাইপডেফের জন্য বর্গের নামের একটি সঠিক অনুলিপি প্রয়োজন। যদি কেউ শ্রেণীর নাম পরিবর্তন করে তবে টাইপডেফ পরিবর্তন না করে তবে আপনি সমস্যার মধ্যে চলে যাবেন।

তাই আমি খুব সাধারণ টেম্পলেট ব্যবহার করে আরও ভাল সমাধান নিয়ে এসেছি।

template <class C>
struct MakeAlias : C
{ 
    typedef C BaseAlias;
};

এখন, পরিবর্তে

class Derived : public Base
{
private:
    typedef Base Super;
};

তোমার আছে

class Derived : public MakeAlias<Base>
{
    // Can refer to Base as BaseAlias here
};

এই ক্ষেত্রে, BaseAliasব্যক্তিগত নয় এবং আমি অন্য প্রবর্তকদের সতর্ক করা উচিত এমন একটি প্রকারের নাম নির্বাচন করে অযত্ন ব্যবহারের বিরুদ্ধে রক্ষা করার চেষ্টা করেছি।


4
publicউপন্যাসটি একটি খারাপ দিক, কারণ আপনি রডির এবং ক্রিস্টোফারের উত্তরগুলিতে উল্লিখিত বাগটি উন্মুক্ত করেছেন (উদাহরণস্বরূপ আপনি এর Derivedপরিবর্তে (ভুল করে) পেতে পারেন MakeAlias<Derived>)
আলেকজান্ডার মালাখভ

3
আপনার প্রারম্ভকালীন তালিকাগুলিতে বেস বর্গ নির্মাণকারীদের অ্যাক্সেসও নেই। (এটি সি ++ 11 এর জন্য উত্তরাধিকারী কনস্ট্রাক্টরগুলি MakeAliasবা নিখুঁত ফরোয়ার্ডিং ব্যবহার করে ক্ষতিপূরণ দেওয়া যেতে পারে তবে এটির জন্য MakeAlias<BaseAlias>কেবল আপনার Cনির্মাণকারীর সরাসরি উল্লেখ না করে আপনি কনস্ট্রাক্টরগুলি উল্লেখ করা প্রয়োজন ))
অ্যাডাম এইচ পিটারসন

12

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


6
কেবল এই বাক্যাংশটির জন্য উক্তি করুন, "এমন কিছু নেই যা বলে যে কিছু কার্যকর হওয়ার জন্য সর্বত্র ব্যবহারযোগ্য হতে হবে।"
টঙ্কটালাস

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

9

আমি এই আইডিয়োমটি অনেকগুলি কোডে নিযুক্ত দেখেছি এবং আমি নিশ্চিত যে এটি বুস্টের লাইব্রেরিতে কোথাও দেখেছি। তবে যতদূর আমার মনে আছে সর্বাধিক প্রচলিত নামটি base(বা Base) পরিবর্তে super

টেম্পলেট শ্রেণীর সাথে কাজ করে এই আইডিয়ামটি বিশেষভাবে কার্যকর। উদাহরণ হিসাবে, নিম্নলিখিত শ্রেণীর বিবেচনা করুন ( বাস্তব প্রকল্প থেকে ):

template <typename TText, typename TSpec>
class Finder<Index<TText, PizzaChili<TSpec> >, PizzaChiliFinder>
    : public Finder<Index<TText, PizzaChili<TSpec> >, Default>
{
    typedef Finder<Index<TText, PizzaChili<TSpec> >, Default> TBase;
    // …
}

মজার নামগুলি মনে করবেন না। এখানে গুরুত্বপূর্ণ বিষয়টি হ'ল উত্তরাধিকার শৃঙ্খলা সংকলন-কাল পলিমারফিজম অর্জনের জন্য ধরণের যুক্তি ব্যবহার করে। দুর্ভাগ্যক্রমে, এই টেম্পলেটগুলির নেস্টিং স্তরটি বেশ উচ্চতর হয়। সুতরাং, পাঠযোগ্যতা এবং রক্ষণাবেক্ষণের জন্য সংক্ষিপ্ত বিবরণগুলি গুরুত্বপূর্ণ।


আমি খুব সম্প্রতি একই কারণে "সুপার" ব্যবহার করেছি। জনসাধারণের উত্তরাধিকার হ্যান্ডেল করা খুব বেদনাদায়ক ছিল ... অন্যথায় ... :-) ...
প্যারাসেবল

4

আমি প্রায়শই এটি ব্যবহার করে দেখেছি, কখনও কখনও সুপার_ টি হিসাবে, যখন বেসটি কোনও জটিল টেম্পলেট ধরণের হয় ( boost::iterator_adaptorউদাহরণস্বরূপ এটি করে)


1
তুমি ঠিক বলছো. আমি এখানে রেফারেন্স পেয়েছি। boost.org/doc/libs/1_36_0/libs/iterator/doc/…
প্যাসেরেবল

4

টাইপএফের ব্যবহারটি কি সুপার / সাধারণ / বিরল / আপনি যে কোডটি ব্যবহার করেন তার মধ্যে কখনই দেখা যায় না?

আমি যে সি ++ কোড দিয়ে কাজ করি সেটিতে আমি এই নির্দিষ্ট প্যাটার্নটি কখনই দেখিনি, তবে এর অর্থ এই নয় যে এটি বাইরে নেই।

টাইপেফ সুপার ওকের এই ব্যবহারটি (যেমন আপনি এটি ব্যবহার না করার জন্য দৃ strong় বা এত শক্ত কারণ দেখেন না)?

এটি একাধিক উত্তরাধিকারের জন্য অনুমতি দেয় না (পরিষ্কারভাবে, যাইহোক)।

"সুপার" ভাল জিনিস হওয়া উচিত, এটি কি কিছুটা সি ++ তে প্রমিত করা উচিত, নাকি টাইপডিফের মাধ্যমে এটি ইতিমধ্যে যথেষ্ট?

উপরোক্ত উদ্ধৃত কারণে (একাধিক উত্তরাধিকার), না। আপনি তালিকাভুক্ত অন্যান্য ভাষায় আপনি কেন "সুপার" দেখছেন তা হ'ল তারা কেবল একক উত্তরাধিকারকে সমর্থন করে তাই "সুপার" কী বোঝায় তা নিয়ে কোনও বিভ্রান্তি নেই। মঞ্জুর, এই ভাষাগুলিতে এটি দরকারী তবে এটি সি ++ ডেটা মডেলটিতে আসলেই স্থান পায় না।

ওহ, এবং এফওয়াইআই: সি ++ / সিএলআই "__সুপার" কীওয়ার্ড আকারে এই ধারণাটি সমর্থন করে। দয়া করে নোট করুন, যদিও, সি ++ / সিএলআই একাধিক উত্তরাধিকার সমর্থন করে না।


4
কাউন্টার-পয়েন্ট হিসাবে, পারেলের একাধিক উত্তরাধিকার এবং সুপার উভয়ই রয়েছে । কিছু বিভ্রান্তি আছে, তবে ভিএম কিছু খুঁজে পেতে যে অ্যালগরিদমটি স্পষ্ট করে নথিভুক্ত করা হয়। এটি বলেছিল, আমি খুব কমই এমআই ব্যবহার করতে দেখি যেখানে একাধিক বেস ক্লাস একই পদ্ধতি প্রদান করে যেখানে যেভাবে বিভ্রান্তি দেখা দিতে পারে।
টঙ্কটালাস

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

3

সুপারক্লাসের জন্য টাইপিডেফ ব্যবহার করার একটি অতিরিক্ত কারণ হ'ল আপনি যখন বস্তুর উত্তরাধিকারের জটিল টেম্পলেট ব্যবহার করছেন।

এই ক্ষেত্রে:

template <typename T, size_t C, typename U>
class A
{ ... };

template <typename T>
class B : public A<T,99,T>
{ ... };

বি ক্লাসে এ এর ​​জন্য টাইপিডেফ রাখা আদর্শ হবে অন্যথায় আপনি এ এর ​​সদস্যদের রেফারেন্স করতে চাইলে সর্বত্র এটি পুনরাবৃত্তি করতে আটকে যাবেন।

এই ক্ষেত্রে এটি একাধিক উত্তরাধিকারের সাথেও কাজ করতে পারে তবে আপনার কাছে 'সুপার' নামে কোনও টাইপেইফ নেই, এটিকে 'বেস_এ_টি' বা এর মতো কিছু বলা হবে।

--jeffk ++,


2

দিনে টার্বো পাস্কাল থেকে সি ++ এ ফিরে যাওয়ার পরে, টার্বো পাসকালের "উত্তরাধিকারসূত্রে" কীওয়ার্ডের সমতুল্য হওয়ার জন্য আমি এটি করতাম, যা একইভাবে কাজ করে। তবে কয়েক বছর সি ++ এ প্রোগ্রাম করার পরে আমি এটি করা বন্ধ করে দিয়েছি। আমি খুঁজে পেয়েছি যে আমার এটির খুব বেশি দরকার নেই।


1

আমি জানি না এটি বিরল কি না, তবে আমি অবশ্যই একই কাজ করেছি।

যেমন নির্দেশিত হয়েছে, ভাষার এই অংশটি তৈরি করতে সমস্যাটি তখনই হয় যখন কোনও শ্রেণি একাধিক উত্তরাধিকার ব্যবহার করে।


1

আমি এটি সময়ে সময়ে ব্যবহার করি। মাত্র যখন আমি কয়েক বার বেস ক্লাসের টাইপটি টাইপ করতে দেখি, তখন আমি এটির সাথে আপনার মতো টাইপডেফটি প্রতিস্থাপন করব।

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

আমি মনে করি টাইপিডের মাধ্যমে ব্যবহার ইতিমধ্যে যথেষ্ট enough এটি যেভাবে যাইহোক ভাষাতে তৈরি করা যায় তা আমি দেখতে পাচ্ছি না কারণ একাধিক উত্তরাধিকার মানে অনেকগুলি বেস ক্লাস থাকতে পারে, সুতরাং আপনি যে ক্লাসের জন্য উপযুক্ত মনে করছেন আপনি এটি সবচেয়ে গুরুত্বপূর্ণ বেস ক্লাস হিসাবে উপযুক্ত হিসাবে দেখতে পারেন typ


1

আমি এই একই সমস্যাটি সমাধান করার চেষ্টা করছিলাম; আমি অভিভাবকদের একটি স্বেচ্ছাসেবী সংখ্যার জন্য অনুমতি দেওয়ার জন্য ভ্যারিয়েডিক টেম্পলেট এবং প্যাক সম্প্রসারণের মতো কয়েকটি ধারণা নিক্ষেপ করেছি, কিন্তু আমি বুঝতে পেরেছিলাম যে 'সুপার0' এবং 'সুপার 1' এর মতো একটি বাস্তবায়ন ঘটবে। আমি এটিকে ট্র্যাশ করেছি কারণ এটি শুরু না করার চেয়ে সবেমাত্র বেশি কার্যকর হবে।

আমার সলিউশনটিতে একজন সহায়ক শ্রেণি জড়িত PrimaryParentএবং তাই প্রয়োগ করা হয়েছে:

template<typename BaseClass>
class PrimaryParent : virtual public BaseClass
{
protected:
    using super = BaseClass;
public:
    template<typename ...ArgTypes>
    PrimaryParent<BaseClass>(ArgTypes... args) : BaseClass(args...){}
}

তারপরে আপনি কোন ক্লাসটি ব্যবহার করতে চান তা ঘোষিত হবে:

class MyObject : public PrimaryParent<SomeBaseClass>
{
public:
    MyObject() : PrimaryParent<SomeBaseClass>(SomeParams) {}
}

ভার্চুয়াল উত্তরাধিকার ব্যবহার করতে প্রয়োজন এড়াতে PrimaryParentউপর BaseClass, একটি কন্সট্রাকটর আর্গুমেন্ট একটি পরিবর্তনশীল সংখ্যা গ্রহণের নির্মাণ করার অনুমতি ব্যবহার করা হয় BaseClass

পিছনে কারণ publicএর উত্তরাধিকার BaseClassমধ্যে PrimaryParentদেওয়া হয় MyObjectএর উত্তরাধিকার উপর সম্পূর্ণ নিয়ন্ত্রণ থাকবেBaseClass তাদের মধ্যে একটি সাহায্যকারী বর্গ থাকা সত্বেও।

এর অর্থ এই নয় যে আপনি যে ক্লাসটি পেতে চান তা superঅবশ্যই PrimaryParentসহায়ক শ্রেণিটি ব্যবহার করতে হবে এবং প্রতিটি শিশু কেবলমাত্র একটি শ্রেণীর কাছ থেকে উত্তরাধিকারী হতে পারে PrimaryParent(তাই নামটি ব্যবহার করে )।

এই পদ্ধতির জন্য অন্য বিধিনিষেধটি হ'ল MyObjectউত্তরাধিকার সূত্রে প্রাপ্ত এক শ্রেণীর উত্তরাধিকারী PrimaryParentহতে পারে এবং এটি ব্যবহার করে উত্তরাধিকার সূত্রে প্রাপ্ত হতে হবে PrimaryParent। আমি যা বলতে চাইছি তা এখানে:

class SomeOtherBase : public PrimaryParent<Ancestor>{}

class MixinClass {}

//Good
class BaseClass : public PrimaryParent<SomeOtherBase>, public MixinClass
{}


//Not Good (now 'super' is ambiguous)
class MyObject : public PrimaryParent<BaseClass>, public SomeOtherBase{}

//Also Not Good ('super' is again ambiguous)
class MyObject : public PrimaryParent<BaseClass>, public PrimaryParent<SomeOtherBase>{}

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

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

superপ্রতিটি ক্লাসে সংজ্ঞায়িত করার ধারণাটি আমার কাছে খুব আবেদনকারী নয় , স্পষ্টতই উত্তরাধিকার ভিত্তিক একটি উপন্যাস ব্যবহার করে ক্লাস বডি যেখানে ডেটা উচিত সেখানকার পরিবর্তে ক্লাস সংজ্ঞা লাইনে থাকার PrimaryParentঅনুমতি দেয় super

এটা যদিও আমার হতে পারে।

অবশ্যই প্রতিটি পরিস্থিতি আলাদা, তবে কোন বিকল্পটি ব্যবহার করবেন তা সিদ্ধান্ত নেওয়ার সময় আমি এই বিষয়গুলি বলেছি consider


1

আমি মন্তব্যগুলির সাথে উপস্থিত কোড ব্যতীত বেশি কিছু বলব না যা প্রমাণ করে যে সুপারটি কল কলিংয়ের অর্থ নয়!

super != base.

সংক্ষেপে, "সুপার" মানে যাইহোক বোঝা যাচ্ছে? এবং তারপরে "বেস" এর অর্থ কী?

  1. সুপার মানে, কোনও পদ্ধতির শেষ প্রয়োগকারীকে কল করা (বেস পদ্ধতি নয়)
  2. বেস মানে, একাধিক উত্তরাধিকারের ক্ষেত্রে কোন শ্রেণীটি ডিফল্ট বেস is

এই 2 টি বিধি ক্লাস টাইপডেফগুলিতে প্রযোজ্য।

গ্রন্থাগার বাস্তবায়নকারী এবং গ্রন্থাগারের ব্যবহারকারী বিবেচনা করুন, কে সুপার এবং কে বেস?

আরও তথ্যের জন্য এখানে আপনার আইডিইতে অনুলিপি করার জন্য কোড কাজ করছে:

#include <iostream>

// Library defiens 4 classes in typical library class hierarchy
class Abstract
{
public:
    virtual void f() = 0;
};

class LibraryBase1 :
    virtual public Abstract
{
public:
    void f() override
    {
        std::cout << "Base1" << std::endl;
    }
};

class LibraryBase2 :
    virtual public Abstract
{
public:
    void f() override
    {
        std::cout << "Base2" << std::endl;
    }
};

class LibraryDerivate :
    public LibraryBase1,
    public LibraryBase2
{
    // base is meaningfull only for this class,
    // this class decides who is my base in multiple inheritance
private:
    using base = LibraryBase1;

protected:
    // this is super! base is not super but base!
    using super = LibraryDerivate;

public:
    void f() override
    {
        std::cout << "I'm super not my Base" << std::endl;
        std::cout << "Calling my *default* base: " << std::endl;
        base::f();
    }
};

// Library user
struct UserBase :
    public LibraryDerivate
{
protected:
    // NOTE: If user overrides f() he must update who is super, in one class before base!
    using super = UserBase; // this typedef is needed only so that most derived version
    // is called, which calls next super in hierarchy.
    // it's not needed here, just saying how to chain "super" calls if needed

    // NOTE: User can't call base, base is a concept private to each class, super is not.
private:
    using base = LibraryDerivate; // example of typedefing base.

};

struct UserDerived :
    public UserBase
{
    // NOTE: to typedef who is super here we would need to specify full name
    // when calling super method, but in this sample is it's not needed.

    // Good super is called, example of good super is last implementor of f()
    // example of bad super is calling base (but which base??)
    void f() override
    {
        super::f();
    }
};

int main()
{
    UserDerived derived;
    // derived calls super implementation because that's what
    // "super" is supposed to mean! super != base
    derived.f();

    // Yes it work with polymorphism!
    Abstract* pUser = new LibraryDerivate;
    pUser->f();

    Abstract* pUserBase = new UserBase;
    pUserBase->f();
}

এখানে আর একটি গুরুত্বপূর্ণ বিষয় হ'ল:

  1. পলিমারফিক কল: কলকে নীচের দিকে
  2. সুপার কল: উপরের দিকে কল

এর ভিতরে main()আমরা পলিমারফিক কল ডাউনড ব্যবহার করি যা সুপারগুলি উপরের দিকে কল করে, বাস্তব জীবনে সত্যই কার্যকর নয়, তবে এটি তফাতটি দেখায়।



0

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

উদাহরণ স্বরূপ:

// some header.h

#define CLASS some_iterator
#define SUPER_CLASS some_const_iterator
#define SUPER static_cast<SUPER_CLASS&>(*this)

template<typename T>
class CLASS : SUPER_CLASS {
   typedef CLASS<T> class_type;

   class_type& operator++();
};

template<typename T>
typename CLASS<T>::class_type CLASS<T>::operator++(
   int)
{
   class_type copy = *this;

   // Macro
   ++SUPER;

   // vs

   // Typedef
   // super::operator++();

   return copy;
}

#undef CLASS
#undef SUPER_CLASS
#undef SUPER

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

superজাভাতে দেখা আচরণের প্রতিলিপি করতে কেউ একটি ছোট-ছোট কেস ব্যবহার করতে পারে তবে আমার কোডিং স্টাইলটি ম্যাক্রোগুলির জন্য সমস্ত বড় হাতের অক্ষর ব্যবহার করা।

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