2012-02-06 13 views
7

मैं एक कठिन समय है कि मैं क्या इतना पूछना मैं आपको एक उदाहरण देता हूँ करने के लिए कोशिश कर रहा हूँ का सवाल बनाने में आ रही वाक्य रचना अधिक भार:बेसिक ऑपरेटर C++

हम एक 3 डी प्रणाली है जहाँ हम पर काम कर रहे कहो एक वेक्टर वर्ग, Vec3 परिभाषित किया। हम स्पष्ट रेजोन के लिए कुछ अंकगणितीय ऑपरेटरों को अधिभारित करते हैं। इनमें से हम * ऑपरेटर को अधिभारित करते हैं ताकि वह दो वैक्टरों के डॉट उत्पाद को वापस कर दे। अब हमारी कोड कुछ इस तरह दिखना चाहिए:

class Vec3{ 
private: 
    float x, y, z; 
public: 
    float operator*(const Vec3&) const; //dot product 
. 
. 
. 

अब कहते हैं कि हमें कुछ के साथ * ऑपरेटर का उपयोग करके हमारे वेक्टर पैमाने पर करने में सक्षम होना चाहते हैं, एक नाव का कहना है। इस घोषणा के द्वारा किया जा सकता है निम्नलिखित:

Vec3 operator*(const float) const; 
    friend Vec3 operator*(const float, const Vec3&); 

यह दो भार के और सिर्फ एक साथ यह करने के लिए कोई तरीका है मैं सोच रहा हूँ, यानी कहते हैं कि हम ऊपर दो पंक्तियों के बजाय इस घोषित yeilds:

friend Vec3 operator*(const Vec3&, const Vec3&); 

और फिर फ्लोट से कनवर्टन को संभालने के लिए Vec3 ctor के लिए डिफ़ॉल्ट मान जोड़ें।

Vec3 someVec3 = 1.0 * otherVec3; //through friend Vec3 operator*(const float, const Vec3&) 
लेकिन नहीं

इस के लिए:

Vec3 someVec3 = otherVec3 * 1.0; 

के रूप में संकलक पता नहीं दोनों में से कौन उपयोग करने के लिए:

यह पिछले उदाहरण के लिए काम करेगा

friend Vec3 operator*(const float, const Vec3&); //the one we want to use 
or 
    float operator*(const Vec3&) const; //the one for the dot product 

कोई सुझाव?

धन्यवाद!

+3

दो ओवरलोड के साथ क्या गलत है? जैसा कि आप इंगित करते हैं, जब आप इसे अधिक विस्तारित करने का प्रयास करते हैं तो एक बदसूरत अस्पष्टता बनाई जाती है ... –

+2

एकमात्र चीज जो मैं अलग-अलग करूँगा, स्केलर के दोनों संस्करणों को एक सदस्य होने के बजाय मित्र कार्यों को गुणा करना है, ताकि कोड होगा ऑपरेशन के रूप में एक ही समरूपता है। –

+0

यह एक फ्लोट पास करने के लिए एक वेक्टर बनाने के लिए अक्षम होगा। यह एक रन टाइम अक्षमता होगी लेकिन एक अतिरिक्त ओवरलोडेड फ़ंक्शन को रेखांकित किया जा सकता है। – QuentinUK

उत्तर

5

इस मामले मैं शुरू में ऑपरेटर ओवरलोडिंग के खिलाफ सलाह देंगे, क्योंकि कैसे हैं तथा आपके उपयोगकर्ताओं जानना चाहते हैं कि * डॉट या पार उत्पाद (दोनों की उम्मीद ग्राहक उपयोग के आधार पर उचित अर्थ) का प्रतिनिधित्व करता है। मैं वास्तव में सुझाव देता हूं कि operator* का समर्थन न करें और dot, cross और scale सदस्यों के साथ ऐसा करें। फिर आपको एकाधिक ओवरलोड के बारे में चिंता करने की ज़रूरत नहीं है और यह आपके उपयोगकर्ताओं को यह स्पष्ट है कि वे क्या प्राप्त कर रहे हैं।

हालांकि यदि आप ऑपरेटरों के साथ आगे बढ़ना चाहते हैं, तो दो ओवरलोड होने में कुछ भी गलत नहीं है। स्केलिंग करने के लिए एक डमी Vec3 बनाना न केवल अर्थात् गलत है, यह अनियंत्रित ओवरहेड की एक छोटी राशि को जोड़ने जा रहा है।

1

खासकर यदि वे एक दूसरे को आसानी के मामले में लागू किया जा सकता नहीं भार के के एक जोड़े में कुछ भी गलत नहीं, नहीं है:

Vec3 operator*(const float scale, const Vec3& vec) 
{ return vec * scale; } 

यह है कि से अधिक आसान पाने के लिए कठिन है!

2

Boost.Operators आपके लिए बॉयलर-प्लेट काम का अधिकांश हिस्सा कर सकता है। उदा .:

class Vec3 
    : boost::multipliable2<Vec3, float> 
{ 
public: 
    // ... 

    Vec3 operator*=(float); 
    // Vec3 operator*(Vec3, const float&) and 
    // Vec3 operator*(const float&, Vec3) auto-generated 
    // by multipliable. 
}; 
संबंधित मुद्दे