8

से निरंतर ऑब्जेक्ट को गुणा करना मेरे पास Matrix वर्ग है और यह स्केलर और मैट्रिक्स गुणाओं के लिए * ऑपरेटरों को अधिभारित कर चुका है।बाएं तरफ

template <class T> class Matrix 
{ 
    public: 
     // ... 
     Matrix operator*(T scalar) const; 
     // ... 
} 

// ... 

template <class T> 
Matrix<T> Matrix<T>::operator*(T RightScalar) const 
{ 
    Matrix<T> ResultMatrix(m_unRowSize, m_unColSize); 
    for (uint64_t i=0; i<m_unRowSize; i++) 
    { 
     for (uint64_t j=0; j<m_unColSize; j++) 
     { 
      ResultMatrix(i, j) = TheMatrix[m_unColSize * i + j] * RightScalar; 
     } 
    } 
    return ResultMatrix; 
} 

// ... 

मैं बिना किसी समस्या के दाईं ओर से एक अदिश के साथ एक मैट्रिक्स वस्तु गुणा कर सकते हैं:

Matrix<double> X(3, 3, /* ... */); // Define a 3x3 matrix and initialize its contents 
Matrix<double> Y;     // Define an output matrix 
Y = X * 10.0;      // Do the linear operation 

लेकिन, मैं इसे कैसे बाईं ओर उसी तरह से गुणा करते हैं?

Matrix<double> X(3, 3, /* ... */); 
Matrix<double> Y; 
Y = 10.0 * X; 

अंकगणित में, गुणा करने के दौरान बाएं तरफ स्थिरांक लिखना एक आम धारणा है। मैं अपने कोड को और अधिक पठनीय बनाने के लिए इस नियम का पालन करना चाहता हूं।

क्या इसे सी ++ में कार्यान्वित करना संभव है?
यदि यह संभव है, तो मैं अपने कोड में कक्षा विधि को कैसे संशोधित करूं?

+2

यह संभव है, लेकिन कक्षा विधि के साथ नहीं। – Kimi

उत्तर

9

सदस्य फ़ंक्शंस उनके बाएं हाथ के पक्ष तर्क से मेल खाते हैं जो यह सूचक है। चूंकि देशी प्रकारों में सदस्य कार्य नहीं हो सकते हैं, इसलिए आपको गैर-सदस्य कार्यों के माध्यम से उपयोगकर्ता द्वारा परिभाषित प्रकारों के साथ दाएं-गुणा जोड़ना होगा (और अन्य प्रकारों के लिए जिनके पास आपके पास लेखन-पहुंच नहीं है)।

template<typename T> 
Matrix<T> operator*(T const& scalar, Matrix<T> rhs) 
{ 
    // scalar multiplication is commutative: s M = M s 
    return rhs *= scalar; // calls rhs.operator*=(scalar); 
} 

नोट: मैं ऊपर गैर सदस्य operator* एक सदस्य operator*= के मामले में लागू किया लिखा था। गैर-सदस्य कार्यों के रूप में सभी गुणाओं को लिखने की सिफारिश की जाती है, और एक एलएचएस मैट्रिक्स तत्व के साथ इन गुणाओं को लागू करने के लिए सदस्य operator*= का उपयोग करें।

यह एक होगा) कक्षा इंटरफ़ेस को न्यूनतम रखें, और बी) छुपा रूपांतरणों को रोकें। जैसे यदि आपके पास आयाम 1x1 हैं, तो आपके पास एक मैट्रिक्स क्लास हो सकता है जो कि आयाम के लिए स्पष्ट रूप से परिवर्तनीय है, और यदि आप एक अलग अधिभार प्रदान नहीं करते हैं तो यह रूपांतरण चुपचाप हो सकता है।

template<typename T> 
Matrix<T> operator*(Matrix<T> lhs, T const& scalar) 
{ 
    return lhs *= scalar; // calls lhs.operator*=(scalar); 
} 

template<typename T> 
Matrix<T> operator*(Matrix<T> lhs, Matrix<T> const& rhs) 
{ 
    return lhs *= rhs; // calls lhs.operator*=(rhs); 
} 

इस बात पर ध्यान दें कि एलएचएस मैट्रिक्स एक प्रतिलिपि है और संदर्भ नहीं है। यह संकलक को अनुकूलन करने की अनुमति देता है जैसे प्रतिलिपि/चाल semantics। यह भी ध्यान रखें कि इन ऑपरेटरों का रिटर्न प्रकार Matrix<T> है और const Matrix<T> नहीं है, जिसे कुछ पुरानी सी ++ किताबों में अनुशंसित किया गया था, लेकिन सी ++ 11 में चलती शब्दावली को रोकता है।

// class member 
template<typename T> 
Matrix<T>& Matrix<T>::operator*=(Matrix<T> const& rhs) 
{ 
    // your implementation 
    return *this; 
} 

// class member 
template<typename T> 
Matrix<T>& Matrix<T>::operator*=(T const& scalar) 
{ 
    // your implementation 
    return *this; 
} 
8

आपको लगता है कि के लिए एक गैर सदस्य समारोह की आवश्यकता होगी: जबकि सदस्य भार के हमेशा बाएं हाथ पर वस्तु मिलता है,

template <typename T> 
Matrix<T> operator*(T scalar, Matrix<T> const & matrix) { 
    return matrix * scalar; 
} 

गैर-सदस्य ऑपरेटर भार के आप दोनों तरफ किसी भी प्रकार निर्दिष्ट कर सकते हैं पक्ष।