سؤال

هل هناك طريقة لإضافة طرق جديدة إلى فئة دون تعديل الأصلي تعريف الفئة (أيجمعت .ليب تحتوي الطبقة المقابلة .ساعة الملف) مثل C#'ق الدرجة امتداد الطرق ؟

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

المحلول

لا.C++ لا يوجد لديه مثل هذه القدرة.

كما ورد في إجابات أخرى المشتركة الحلول هي:

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

نصائح أخرى

لا, لا يمكنك فعل هذا في C++.

إذا كنت ترغب في تحقيق شيء من هذا القبيل لديك 2 الخيارات ،

  • هل يمكن أن ترث من فئة (إذا كان هذا الخيار قد لا يكون قانونيا في طبقة قد لا يكون مكتوب للسماح الميراث)
  • يمكنك كتابة الخاصة بك المجمع الدرجة التي لديه نفس واجهة + الجديد الخاص بك أساليب مندوب واحد كنت ترغب في تمديد.

انا افضل الوفد النهج.

وطرق الإرشاد C # الطبقة هي السكر في الغالب النحوي. يمكنك الحصول على نفس وظائف وظائف خالية (أي وظائف مع إشارة أو الإشارة المستمرة إلى صفك كأول معلمة بهم). لأن هذا يعمل بشكل جيد لSTL، لماذا لا للفئة الخاصة بك؟

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

var r = numbers.Where(x => x > 2).Select(x => x * x);

إذا علينا أن أكتب هذا في C ++ باستخدام وظيفة خالية انها تبدو مثل هذا:

auto r = select(where(numbers, [](int x) { return x > 2; }), [](int x) { return x * x; });

وليس هذا فقط هو من الصعب قراءة، ولكن من الصعب أن يكتب. طريقة مشتركة لحل هذا هو خلق ما يسمى وظيفة pipable. يتم إنشاء هذه الوظائف عن طريق الحمولة الزائدة المشغل الأنابيب | (الذي هو مجرد حقا أو مشغل). لذلك رمز أعلاه يمكن أن تكون مكتوبة مثل هذا:

auto r = numbers | where([](int x) { return x > 2; }) | select([](int x) { return x * x; });

ما هو أسهل بكثير على القراءة والكتابة. العديد من المكتبات استخدام وظيفة pipable لنطاقات، ولكن يمكن توسيعها لتشمل فئات أخرى أيضا. يستخدم دفعة في rel="nofollow"> مكتبة، يستخدم pstade فرن في هذا الشأن وأيضا هذا C ++ LINQ تستخدم مكتبة أنها كذلك.

إذا كنت ترغب في إرسال ظيفة pipable الخاصة بك، وتعزيز شرح كيفية القيام بذلك <لأ href = "http://www.boost.org/doc/libs/1_52_0/libs/range/doc/html/range /reference/extending/method_3/method_3_2.html "يختلط =" نوفولو "> هنا . مكتبات أخرى، ومع ذلك، وتوفير محولات وظيفة لجعله أسهل. Pstade البيض لديه pipable محول ، وينق يوفر محول range_extension إنشاء دالة pipable لنطاقات كما الأقل.

<ع> استخدام LINQ، عليك أولا مجرد إنشاء وظيفة الخاص بك ككائن وظيفة مثل هذا:

struct contains_t
{
    template<class Range, class T>
    bool operator()(Range && r, T && x) const
    { return (r | linq::find(x)) != boost::end(r); };
};

وبعد ذلك يمكنك تهيئة الدالة باستخدام التهيئة ثابتة مثل هذا:

range_extension<contains_t> contains = {};

وبعد ذلك يمكنك استخدام وظيفة pipable الخاصة بك مثل هذا:

if (numbers | contains(5)) printf("We have a 5");

عموما لا.ومع ذلك ، إذا كانت المكتبة لا إنشاء مثيلات الفئة التي تتطلب تمديد كنت قادرا على تعديل جميع الأماكن في التطبيق إنشاء مثيل فئة تتطلب ملحقات هناك طريقة يمكنك الذهاب:

  • إنشاء مصنع وظيفة الذي يسمى في كل الأماكن التي تتطلب مثيل من فئة بإرجاع مؤشر على سبيل المثال (جوجل أنماط تصميم مصنع, ...).
  • إنشاء فئة مشتقة مع امتداد تريد.
  • جعل وظيفة مصنع العودة الخاص بك فئة مشتقة بدلا من الطبقة الأصلية.

على سبيل المثال:


    class derivedClass: public originalClass { /* ... */};

    originalClass* createOriginalClassInstance()
    {
         return new derivedClass();
    }
  • كلما كنت بحاجة إلى الوصول إلى ملحقات تحتاج إلى الزهر الزهر الأصلي إلى فئة مشتقة بالطبع.

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

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

وهذا هو وظائف غير الأعضاء التي يمكن أن تعطى الدرجة كمعلمة ينبغي النظر

و، وهي جزء من واجهة.

وعلى سبيل المثال، std::find() أو std::sort() هي جزء من واجهة std::vector، على الرغم من أنهم ليسوا أعضاء في الطبقة.

وإذا كنت تقبل هذا التعريف، ثم يمكنك توسيع دائما فئة ببساطة عن طريق إضافة وظائف غير عضو.

ولا يمكنك إضافة الأساليب أو البيانات فعليا إلى ملف فئة الذي هو في شكل ثنائي. ومع ذلك، يمكنك إضافة أساليب والبيانات (وظائف والدولة) إلى الكائنات من تلك الفئة من خلال كتابة فصول التمديد. هذا ليس مباشرة إلى الأمام، ويتطلب ميتا كائن البروتوكول واجهة البرمجة القائمة. تحتاج إلى القيام بالكثير لتحقيق هذا في C ++ لأنه لا يدعم التفكير من خارج منطقة الجزاء. في مثل هذا التنفيذ عند الاستعلام للواجهة التي تنفذها الطبقة تمديد جديدة عن طريق مؤشر كائن الفئة الأصلي، وتنفيذ الكائن ميتا يعود هذا المؤشر واجهة عبر كائن الفئة الفوقية لفئة تمديد أنه يخلق في وقت التشغيل. هذه هي الطريقة التي تعمل العديد من تخصيص الأطر التطبيق (البرنامج المساعد القائم) البرمجيات. ومع ذلك، يجب أن نتذكر أنه يتطلب العديد من الآليات MOP الأخرى المراد كتابتها إلى instanciate الأجسام الفوقية لجميع الطبقات باستخدام القواميس التي توصف العلاقات الكائن وتعطي مؤشرات واجهة الصحيحة للكائنات فئة الأصلية وممتدة. هو مكتوب Systèmes داسو 'كاتيا V5 في هذا الهيكل يسمى CAA V5 حيث يمكنك توسيع مكونات القائمة من خلال كتابة فصول تمديد جديدة مع وظيفة المطلوبة.

عذرا، لا. مرة واحدة التعليمات البرمجية في الكائنات، لا يمكنك تغييره. إذا كان هذا يمكن أن يتم في فئات جزئية VC أن تكون معتمدة من قبل. وهناك استثناء واحد على الرغم من أساليب المشغل يمكن توسيعها باستخدام وظائف العالمية، جميلة مثل كيف محكمة << ينفذ في STL.

وبالتأكيد يمكنك:


template <typename Ext>
class Class: public Ext { /* ... */ };

وهذا لا يعني أنها أفضل نهج بالرغم من ذلك.

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