यहाँ एक बहुत ही सरल वर्ग पदानुक्रम है:कहां चाहिए! = ऑपरेटर को कक्षा पदानुक्रम में परिभाषित किया जाना चाहिए?
class A
{
public:
A(int _a) : a(_a) {}
virtual bool operator==(const A& right) const
{
return a == right.a;
}
virtual bool operator!=(const A& right) const
{
return !(*this == right);
}
int a;
};
class B : public A
{
public:
B(int _a, int _b) : A(_a), b(_b) {}
virtual bool operator==(const B& right) const
{
return A::operator==(right) && b == right.b;
}
int b;
};
आप देख सकते हैं, ऑपरेटर = आधार वर्ग में परिभाषित किया गया है। क्योंकि मैं बहुत आलसी हूं, मैं सभी व्युत्पन्न कक्षाओं में ऐसे सरल कोड को डुप्लिकेट नहीं करना चाहता हूं।
दुर्भाग्यवश, इस कोड के साथ:
A a4(4), a5(5), a4bis(4);
assert(a4 == a4bis);
assert(a4 != a5);
B b1(4,5), b2(4,6);
assert(!(b1 == b2));
assert(b1 != b2); // fails because B::operator== is not called!
b1 != b2
रिटर्न झूठी है, क्योंकि यह A::operator!=
निष्पादित करता है जो कहता है तो A::operator==
बल्कि B::operator==
से (भले ही ऑपरेटर आभासी है, के रूप में व्युत्पन्न वर्ग संस्करण पैरामीटर अलग है, वे कर रहे हैं vtable में लिंक नहीं है)।
तो कक्षा पदानुक्रम के लिए सामान्य तरीके से एड्रेस! = ऑपरेटर का सबसे अच्छा तरीका क्या है?
एक समाधान प्रत्येक वर्ग में यह दोहराने के लिए है, B
तो होगा:
virtual bool operator!=(const B& right) const
{
return !(*this == right);
}
लेकिन यह एक दर्द आप कई श्रेणियां होती हैं जब है .... मैं 30 ....
एक अन्य समाधान एक सामान्य टेम्पलेट दृष्टिकोण है करने के लिए होगा:
template <class T>
bool operator!=(const T& left, const T& right)
{
return !(left == right);
}
लेकिन यह किसी भी !=
ऑपरेटर किसी भी वर्ग द्वारा परिभाषित किया गया नजरअंदाज .... तो यह अगर एक decla जोखिम भरा हो सकता है इसे अलग-अलग लाल करें (या अगर किसी ने ==
को !=
पर कॉल किया है, तो यह अनंत लूप के साथ समाप्त होगा ...)। तो मुझे लगता है कि यह समाधान बहुत असुरक्षित है .... सिवाय इसके कि हम अपने पदानुक्रम के शीर्ष-स्तरीय वर्ग (A
) से प्राप्त सभी वर्गों के लिए टेम्पलेट को सीमित करने के लिए सीमित कर सकते हैं .... लेकिन मैं नहीं करता लगता है कि यह बिल्कुल करने योग्य है।
नोट: मैं अभी तक सी ++ 11 का उपयोग नहीं कर रहा हूं ... इसके बारे में खेद है।
इसके अलावा, वर्तमान में, 'ए (42) == बी (42, 0)' जैसा कि आप केवल 'ए' भाग की तुलना करते हैं ... – Jarod42
स्पष्टता के लिए और यह सुनिश्चित करने के लिए कि ए स्वतंत्र रूप से काम करता रहे (यदि आप ' टी इसे चाहते हैं, आपको इससे बी प्राप्त करने की आवश्यकता नहीं है), लागू करें! = ए, बी, सी, डी और जो भी आपके पदानुक्रम में है। दोबारा अगर आपको उनकी ज़रूरत नहीं है, तो आपको बिल्कुल हासिल करने की आवश्यकता क्यों है? – Robinson