سؤال

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

سؤالي هو أنه عندما لا يزال بإمكاني مقارنة Lvalue للمؤشر إلى مرجع ، لماذا يفضل الأصدقاء؟ (باستخدام إصدار غير متماثل يعطي نفس النتائج مثل متماثل) لماذا تستخدم خوارزميات STL الإصدارات المتماثلة فقط؟

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

المحلول

إذا قمت بتحديد وظيفة المشغل الزائد كدالة عضو ، فإن المترجم يترجم تعبيرات مثل s1 + s2 داخل s1.operator+(s2). وهذا يعني أن وظيفة العضو المفرطة في المشغل يتم الاحتجاج بها في المعامل الأول. هذه هي الطريقة التي تعمل بها وظائف الأعضاء!

ولكن ماذا لو لم يكن المعامل الأول فئة؟ هناك مشكلة كبيرة إذا أردنا أن نتفوق على مشغل حيث لا يكون المعامل الأول نوعًا من الفئة ، بل قل double. لذلك لا يمكنك الكتابة مثل هذا 10.0 + s2. ومع ذلك ، يمكنك كتابة وظيفة العضو المفرطة في المشغل للتعبيرات مثل s1 + 10.0.

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

class Sample
{
 public:
    Sample operator + (const Sample& op2); //works with s1 + s2
    Sample operator + (double op2); //works with s1 + 10.0

   //Make it `friend` only when it needs to access private members. 
   //Otherwise simply make it **non-friend non-member** function.
    friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2
}

اقرأ هذه:
مشكلة بسيطة في الطلب في المعاملات
كيف تعمل وظائف غير الأعضاء على تحسين التغليف

نصائح أخرى

إنه ليس بالضرورة تمييزًا بين friend الحمولة الزائدة للمشغل وأحمال مشغل وظائف الأعضاء كما هي بين عالمي الحمولة الزائدة للمشغل وأحمال مشغل وظائف الأعضاء.

أحد أسباب تفضيل أ عالمي الحمل الزائد للمشغل هو إذا كنت تريد السماح بتعبيرات حيث يظهر نوع الفصل على حقا جانب اليد من عامل ثنائي. فمثلا:

Foo f = 100;
int x = 10;
cout << x + f;

هذا يعمل فقط إذا كان هناك حمولة عالمية للمشغل

Foo Operator + (int x ، const foo & f) ؛

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

بغض النظر ، إذا Foo فقط كان لديه تحميل وظائف العضو الزائد ، مثل:

class Foo
{
  ...
  Foo operator + (int x);
  ...
};

... ثم سنكون قادرين فقط على الحصول على تعبيرات حيث أ Foo يظهر مثيل على اليسار من المشغل الزائد.

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