2010-12-08 19 views
9

मैं सिर्फ स्मार्ट पॉइंटर्स को समझने और मेरा बनाने की कोशिश करने के लिए चारों ओर खेल रहा हूं लेकिन मैं ऐसी स्थिति में आया हूं जिसे मैं पूरी तरह समझ नहीं पा रहा हूं। यहाँ कोड है:असाइनमेंट ऑपरेटर कॉल कन्स्ट्रक्टर क्यों करता है?

#include <iostream> 
template <class T> 
class Holder 
{ 
private: 
     T * obj; 
public: 
     Holder(T * tt) : obj(tt) 
     { 
       std::cout << "ctor : " << tt->dummy << std::endl; 
     } 
     T * operator ->() 
     { 
       return obj; 
     } 
     operator bool() 
     { 
       return obj; 
     } 
     T * const get() const 
     { 
       return obj; 
     } 
     void reset() {swap(0);} 
     void swap(T * other) 
     { 
       obj = other; 
     } 
     Holder & operator = (const Holder& holder) 
     { 
       obj = holder.get(); 
       return *this; 
     } 
     Holder(const Holder & holder) : obj(holder.get()) {} 
}; 

class A 
{ 
public: 
     int dummy; 
     A(int a) : dummy(a) {} 
}; 

int main() 
{ 
     A * a = new A(1); 
     Holder<A> holder(a); 
     A * b = new A(2); 
     holder = b; 

     std::cout << holder->dummy << std::endl; 

     return 0; 
} 

कोड संकलित करता है तथा holder = b; की लाइन पर Holder वर्ग के निर्माता कहा जाता है। मैंने सोचा कि संकलक एक त्रुटि देगा। यह आकलन ऑपरेटर नहीं है लेकिन यह कन्स्ट्रक्टर क्यों कह रहा है?

+0

'Holder', दो कंस्ट्रक्टर्स है जो एक कहा जाता है? – suszterpatt

+0

@suszterpatt: धारक (टी * टीटी) –

उत्तर

13

holder = bb से Holder पर असाइन करने का प्रयास करता है। b टाइप A* है, और holderHolder<A> प्रकार का है।

Holder टेम्पलेट एक ही Holder प्रकार का एक और उदाहरण से काम को परिभाषित करता है, तो संकलक A* से एक रूपांतरणHolder<A> करने के लिए लग रहा है। यह निर्माता को पाता है, और इसका उपयोग करता है।

कंस्ट्रक्टर्स जो वास्तव में एक तर्क लग सकता है अंतर्निहित रूपांतरण के लिए इस्तेमाल किया जा सकता, जब तक कि आप उन्हें explicit कीवर्ड के साथ टैग।

+0

+1 "स्पष्ट" के लिए +1। धन्यवाद। –

0

आपके पास एक कन्स्ट्रक्टर टी * ले रहा है। आपके अभिसरण में एक rhs सूचक है, इसलिए यह उस पॉइंटर के साथ एक temp-obj का निर्माण तर्क के रूप में बनाता है और इसे धारक को असाइन करता है।

4

दोनों कन्स्ट्रक्टर और असाइनमेंट ऑपरेटर को बुलाया जाता है। आप operator = में कुछ प्रिंट करके इसे देख सकते हैं।

ऐसा इसलिए होता है क्योंकि operator = को const Holder & लेने के लिए परिभाषित किया गया है, लेकिन bA * प्रकार का है। तो पहले Holder(T *) कन्स्ट्रक्टर को अस्थायी ऑब्जेक्ट बनाने के लिए कहा जाता है, तो यह ऑब्जेक्ट holderoperator = के माध्यम से असाइन किया गया है।

यदि आप operator =(const T *) परिभाषित करते हैं, तो केवल असाइनमेंट ऑपरेटर को कॉल किया जाएगा।

1

मैं असाइनमेंट ऑपरेटर कि ए * के दाहिने हाथ की ओर ले जाता है के एक संस्करण को नहीं देख पा

A*  a  = new A(1); 
    Holder<A> holder(a); 
    A*  b   = new A(2); 

    // assigning object of type A* to Holder<A> 
    holder = b; 

    // No appropriate assignment operator provide. 
    // But a constructor is available to convert RHS parameter to correct type. 
    // So compiler generates the following code: 

    holder = Holder<A>(b); 

    // There is an appropriate assignment operator for this. 
    // So it compiles. 
संबंधित मुद्दे

 संबंधित मुद्दे