السلام عليكم ورحمة الله وبركاته
يتكرر استخدام العملية >operator كونها العمود الفقري في أي مقارنة ضمن حاويات STL أو توابع المقارنة ;
فعلى سبيل المثال لا الحصر : أي بنى شجرية تستخدم balanced tree مثل std::map أو std::set تستخدم العملية >operator لمقارنة العناصر أثناء الترتيب أو أثناء البحث والوصول لعناصر الشجرة , وكمثال آخر فإن توابع max_element أو min_element تستخدم هذه العملية لمقارنة العناصر والعثور على العنصر الأكبر/أو الأصغر كما تعرّفه هذه العملية , فالعنصر الأكبر هو العنصر الذي تمت مقارنته مع باقي العناصر جميعاً ولم يوجد أي عنصر أكبر منه ,وهكذا ..
وكمثال أخير فإن المقارنة أثناء الترتيب تستخدم أيضاً العملية >operator لتحديد أي العناصر يجب أن يكون أولاً , وأيها يجب أن يكون في نهاية الحاوية أو القائمة انظر للتابع sort.
تظهر أهمية هذه العملية عند إعادة تعريفها , والقالب العام لذلك هو الشكل التالي :
bool operator<(const type&first,const type&second){
//some comparison operators return 'true' if first<second
}حيث type هو نوع العناصر في القائمة.
أينما وجدت عملية المقارنة > فهي تعيد true إذا كان العنصر الأيسر أصغر تماماً من الأيمن , ولها قواعد صارمة لا يمكن تجاوزها وهي :
إذا كان a<b تعطي true فيجب أن يكون b<a يعطي false
إذا كان a<b و b<a يعطيان false فيجب أن يكون a==b تماماً
مثلاً لو كان التابع كما يلي :
bool operator<(const type&first,const type&second){
return true;
}فلن يعمل أي شيء يستخدمه بشكل صحيح , وسيسبب مشاكل لا تحصى ,
يجب أن يكون دائماً :
(a<b) + (b<a) + (a==b) == 1
لنبدأ بإعادة تعريف بعض المعاملات :
نريد أن نعرف المقارنة للبنية التالية :
struct student{ string name; int rank;};النوع student له اسم وتقييم (في اختبار ما )
ونريد أن يكون الطالب الذي تقييمه أعلى ((أكبر)) من الطالب ذو التقييم الأخفض , وإن كان لطالبين نفس التقييم فيجب أن يكون الطالب الذي اسمه يأتي في المعجم قبلاً , هو الطالب الـ((أصغر))
(لاحظ كيف نقول أكبر وأصغر )
حل هذا المثال هو كما يلي :
bool operator<(const student&first,const student&second){
if(first.rank<second.rank)
return true;
else if(first.rank==second.rank){
if(first.name<second.name)
return true;
else
return false;
}
else
return false;
}مثال 2 : لو كان لدينا البية التالية :
struct Elephant{ int size;};ويكون القيل أكبر من فيل آخر إذا كان حجمه أكبر !! ببساطة :
bool operator<(const Elephant&first,const Elephant&second){
return first.size<second.size;
}ماذا لو أردنا ان يكون الفيل أكبر من فيل آخر إذا كان حجمه أصغر ؟
bool operator<(const Elephant&first,const Elephant&second){
return first.size>second.size;
}يمكنك تجربة كتابة الكود التالي داخل الـmain :
Elephant x={4};
Elephant y={5};
cout << x.size<<"<"<<y.size<<endl;
cout << "x" <<"<"<<"y="<<(x<y);ما رأيك لو نقارن حجم فيلين ونقول أن الفيل الأكبر بين فيلين زوجيين هو الفيل ذو الحجم الأكبر ولو كانا فرديين فهو الأصغر ولو كان أحدهما فقط زوجي فهو أكبر من الآخر :p
bool operator<(const student&first,const student&second){
if(first.rank<second.rank)
return true;
else if(first.rank==second.rank){
if(first.name<second.name)
return true;
else
return false;
}
else
return false;
}جرب الكود التالي ولاحظ كيف أصبحت المقارنة مختلفة عن المقارنة البسيطة المعتادة :
Elephant a={4},b={5},c={6},d={7};
cout<<(a<b)<<(b<c)<<(a<c)<<(b<d)<<endl;
غالباً ما توجد نسختان من توابع STL التي تستخدم العملية > , النسخة الأولى تكون افتراضية تستخدم هذه العملية , والنسخة الثانية تستخدم تابعاً يتم تمريره كوسيط , له نفس قواعد العملية >
يكون شكل التابع تماماً كشكل إعادة تعريف العملية > , أي كما يلي :
bool compare(const type&first,const type&second){
//some comparison operators return 'true' if first<second
}والمحتوى هو ذاته .
أرجو أن يكون المقال مفيداً في اعتياد استخدام العملية > بعد إعادة تعريفها . يفترض بهذا المقال أن يكون مساعداً لمقالات أخرى تستخدم هذه العملية في محتواها .
والله ولي التوفيق