هل هناك أي أمثلة حيث * نحتاج * إلى الميراث المحمي في C++؟

StackOverflow https://stackoverflow.com/questions/31867

  •  09-06-2019
  •  | 
  •  

سؤال

بينما رأيت حالات نادرة حيث خاص كانت هناك حاجة إلى الميراث، ولم أواجه قط حالة حيث محمي هناك حاجة إلى الميراث.هل لدى شخص ما مثال؟

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

المحلول

يبدو أن الأشخاص هنا يخطئون بين وراثة الطبقة المحمية والأساليب المحمية.

FWIW، لم أر مطلقًا أي شخص يستخدم وراثة الفئة المحمية، وإذا كنت أتذكر بشكل صحيح، أعتقد أن Stroustrup اعتبر المستوى "المحمي" خطأً في لغة C++.هناك القليل الذي لا يمكنك فعله إذا قمت بإزالة مستوى الحماية هذا واعتمدت فقط على القطاعين العام والخاص.

نصائح أخرى

هناك حالة استخدام نادرة جدًا للميراث المحمي.إنه المكان الذي تريد الاستفادة منه التغاير:

struct base { 
    virtual ~base() {} 
    virtual base & getBase() = 0;
}; 

struct d1 : private /* protected */ base { 
    virtual base & getBase() { 
        return this; 
    } 
}; 

struct d2 : private /* protected */ d1 {
    virtual d1 & getBase () { 
        return this; 
    } 
}; 

حاول المقتطف السابق إخفاء فئته الأساسية، وتوفير رؤية محكومة للقواعد ووظائفها، لأي سبب كان، من خلال توفير وظيفة "getBase".

ومع ذلك، سوف تفشل في البنية d2, ، منذ d2 لا يعرف ذلك d1 مشتق من base.هكذا، covariance لن يعمل.والطريق للخروج من هذا هو اشتقاقهم محميين، بحيث يكون الميراث مرئيا في d2.

مثال مشابه لاستخدام هذا هو عندما تشتق من std::ostream, ، لكن لا تريد أن يكتب أشخاص عشوائيون في ساحة المشاركات الخاصة بك.يمكنك توفير الظاهري getStream الوظيفة التي ترجع std::ostream&.يمكن لهذه الوظيفة القيام ببعض التحضير للتيار للعملية التالية.على سبيل المثال وضع بعض المتلاعبين.

std::ostream& d2::getStream() {
    this->width(10);
    return *this;
}

logger.getStream() << "we are padded";

الأسئلة الشائعة حول C++ Lite يذكر حالة يكون فيها استخدام الميراث الخاص حلاً مشروعًا (انظر [24.3.] أيهما أفضل:التكوين أم الميراث الخاص؟).يحدث ذلك عندما تريد استدعاء الفئة المشتقة من داخل فئة أساسية خاصة من خلال وظيفة افتراضية (في هذه الحالة derivedFunction()):

class SomeImplementationClass
{
protected:
    void service() {
        derivedFunction();
    }

    virtual void derivedFunction() = 0;      

    // virtual destructor etc
};

class Derived : private SomeImplementationClass
{
    void someFunction() {
        service();
    }

    virtual void derivedFunction() {
        // ...
    }

    // ...
};

الآن إذا كنت تريد الاشتقاق من الفئة المشتقة، وتريد استخدامها Base::service() من داخل الفئة المشتقة (قل أنك تريد التحرك Derived::someFunction() إلى الفئة المشتقة)، فإن أسهل طريقة لتحقيق ذلك هي تغيير الميراث الخاص لـ Base للميراث المحمي.

آسف، لا أستطيع التفكير في مثال أكثر تحديدا.أنا شخصياً أحب أن أجعل جميع الميراث علنية لتجنب إضاعة الوقت في مناقشات "هل يجب أن أجعل علاقة الميراث محمية أم خاصة".

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