سؤال

لنفترض أن لدي الإعلان التالي:

class Over1
{
   protected:
      class Under1
      {
      };
};

أعلم أنه يمكنني القيام بما يلي:

class Over2 : public Over1
{
   protected:
        class Under2 : public Under1
        {
        };
};

ولكن هل هناك طريقة للإعلان عن Under2 بدون Over2؟

نظرًا لأنه سيتعين عليك تمديد Over1 لاستخدام أي مشتق من Under1، فقد يبدو هذا سخيفًا، ولكن في هذه الحالة قد يكون هناك 30 نكهة مختلفة من Under1.يمكنني إما:

  • ضعهم جميعًا داخل Over1 :ليست جذابة لأن Over2 قد تستخدم فقط 1 أو 2 منهم
  • ضعها في كل نسخة خاصة بها:ليست جذابة منذ ذلك الحين ، سيتعين عليك ضرب الوراثة من نفس الفصل تقريبًا.
  • ابحث عن طريقة لإنشاء أطفال تحت 1 دون إنشاء أطفال من Over1

فهل هذا ممكن؟

شكرًا.

هل كانت مفيدة؟

المحلول

باستخدام القوالب والتخصصات الصريحة، يمكنك القيام بذلك من خلال إعلان فئة إضافي واحد فقط في Over1.

class Over1
{
protected:
  class Under1
  {
  };

  template <typename T>
  class UnderImplementor;
};

struct Under2Tag;
struct Under3Tag;
struct Under4Tag;

template <>
class Over1::UnderImplementor<Under2Tag> : public Over1::Under1
{
};

template <>
class Over1::UnderImplementor<Under3Tag> : public Over1::Under1
{
};

template <>
class Over1::UnderImplementor<Under4Tag> : public Over1::Under1
{
};

أتمنى أن يساعدك هذا.

نصائح أخرى

أفضل من إنشاء فئات متداخلة، قد ترغب في النظر في تضمين تلك الإغلاقات في مساحة الاسم.بهذه الطريقة، لن تحتاج إلى الطبقة الخارجية لتحصل على الطبقة الداخلية.هناك بعض الحجج الكبيرة المؤيدة والمعارضة في دليل أسلوب جوجل C++.

إذا كنت تريد الحفاظ على حماية Under1، فأنت بحكم التعريف تحتاج إلى الوراثة من Over1 للوصول إليه.أود أن أقترح جعل Under1 عامًا، أو استخدام مساحات الأسماء كما اقترح دوغلاس.

ليس لدي مترجم لاختبارها الآن، لذلك لست متأكدًا على الإطلاق من نجاحها، ولكن يمكنك تجربة هذا:

class Over1
{
   protected:
      class Under1
      {
      };

   public:
      class Under1Interface : public Under1 
      {
      };
};

class Under2 : public Over1::Under1Interface
{
};

أو ربما شيء من هذا القبيل:

class Over1
{
   protected:
      class Under1
      {
      };
};

class Under2 : private Over1, public Over1::Under1
{
};

او حتى:

class Under2;

class Over1
{
   friend class Under2;

   protected:
      class Under1
      {
      };
};

class Under2 : public Over1::Under1
{
};

على الرغم من أن ذلك من شأنه أن يعرض جميع أفراد Over1s إلى Under2 - فمن غير المحتمل أن يكون هذا هو ما تريده.

يبدو وكأنه تصميم غير تقليدي قليلاً بالنسبة لي.لماذا لا تحاول هيكلة التعليمات البرمجية الخاصة بك بشكل مختلف.أعتقد أن هذا قد يكون مرشحًا جيدًا لنمط الديكور، حيث يمكنك تغليف فئتك الأساسية بمصممين مختلفين لتحقيق الوظيفة المطلوبة، ويمكن أن تكون النكهات المختلفة لـ "تحت" عبارة عن ديكورات.مجرد فكرة، من الصعب معرفة ذلك دون معرفة المزيد عن نوايا الكود الخاص بك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top