2010-02-28 12 views
21

मैं हाल ही में पता चला कि C++ आप "समारोह कॉल" ऑपरेटर को ओवरलोड कर सकते हैं एक अजीब तरीके जिसमें आप ऐसा करने के लिए कोष्ठक के दो जोड़ी लिखने के लिए है में,:"फ़ंक्शन कॉल" ऑपरेटर को अधिभारित करने के लिए यह कैसे उपयोगी हो सकता है?

class A { 
    int n; 
public: 
    void operator()() const; 
}; 

और फिर इसे इस तरह का उपयोग करें:

A a; 
a(); 

यह उपयोगी कब है?

+3

फ़ंक्शन ऑब्जेक्ट्स के बारे में पढ़ें। http://en.wikipedia.org/wiki/Function_object – AnT

उत्तर

27

यह "functors" बनाने के लिए इस्तेमाल किया जा सकता है, वस्तुओं है कि कार्यों की तरह कार्य:

class Multiplier { 
public: 
    Multiplier(int m): multiplier(m) {} 
    int operator()(int x) { return multiplier * x; } 
private: 
    int multiplier; 
}; 

Multiplier m(5); 
cout << m(4) << endl; 

ऊपर प्रिंट 20। उपरोक्त लिंक विकिपीडिया लेख अधिक महत्वपूर्ण उदाहरण देता है।

+3

और मुख्य कारण यह है कि आप मकसद चाहते हैं सी ++ में उच्च-आदेश कार्य करना है। –

+1

उदाहरण के लिए, आप इसका विस्तार कर सकते हैं, उदाहरण के लिए, पहली बार एम द्वारा गुणा करके, इसे दूसरी बार एम + 1 से गुणा करें। सामान्य कार्य कॉल के बीच किसी भी राज्य की जानकारी को सहेज नहीं सकते हैं, लेकिन मज़दूर कर सकते हैं। – MatrixFrog

+3

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

1

यदि आप एक वर्ग बना रहे हैं जो फ़ंक्शन पॉइंटर को समाहित करता है, तो इससे उपयोग अधिक स्पष्ट हो सकता है।

4

टेम्पलेट का उपयोग करके लागू एक एल्गोरिदम परवाह नहीं है कि क्या कहा जा रहा है एक कार्य या एक मजेदार है, यह वाक्यविन्यास की परवाह करता है। या तो मानक वाले (उदा। For_each()) या स्वयं का। और मज़ेदारों के पास राज्य हो सकता है, और जब उन्हें बुलाया जाता है तो सभी प्रकार की चीजें करते हैं। कार्यों में केवल स्थिर स्थानीय चर या वैश्विक चर के साथ राज्य हो सकता है।

15

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

class scaled_sine 
{ 
    explicit scaled_sine(float _m) : m(_m) {} 
    float operator()(float x) const { return sin(m*x); } 
    float m; 
}; 

template<typename T> 
float evaluate_at(float x, const T& fn) 
{ 
    return fn(x); 
} 

evaluate_at(1.0, cos); 
evaluate_at(1.0, scaled_sine(3.0)); 
+0

हाँ; फ़ंक्शन-जैसी ऑब्जेक्ट्स वास्तव में सबसे उपयोगी होती हैं जब आपके पास पर्याप्त कमजोर टाइपिंग होती है। सी ++ को यह नहीं मिला है, लेकिन टेम्पलेट्स करते हैं। –

+0

स्केल किए गए साइनइनर में टाइपो मुझे लगता है। –

0

कंपाइलर मज़ेदार और फ़ंक्शन कॉल को भी रेखांकित कर सकता है। हालांकि, यह फ़ंक्शन पॉइंटर को रेखांकित नहीं कर सकता है। इस तरह, फ़ंक्शन कॉल ऑपरेटर का उपयोग करके प्रदर्शन में काफी सुधार हो सकता है जब इसका उपयोग मानक C++ libary एल्गोरिदम के साथ किया जाता है।