2012-02-15 31 views
19

मैं सदस्य कार्यों में से एक के लिए वैकल्पिक तर्क देना चाहता हूं। जब कोई तर्क प्रदान नहीं किया जाता है, तो यह एक सदस्य चर का उपयोग करेगा।सी ++ में किसी डिफ़ॉल्ट चर के रूप में सदस्य चर का उपयोग कैसे करें?

हालांकि, जब मैं यह संकलन करने की कोशिश की यह पता चलता है "त्रुटि: गैर स्थैतिक डेटा सदस्य 'वस्तु :: initPos' के अवैध उपयोग"

बस समस्या को अलग करने, किसी पूर्णांक प्रकार मैं दोषी की कोशिश की और यह ठीक संकलित। मुझे आश्चर्य है कि मेरे कोड में समस्या क्या है और मैं सदस्य फ़ंक्शन को डिफ़ॉल्ट मान के रूप में कैसे उपयोग कर सकता हूं।

आपकी मदद के लिए धन्यवाद!

Object.h

class Object 
{ 
    public: 
     ... 
     void MoveTo(double speed, Point position); 

    protected: 
     Point initPos; 
     Point currPos; 

}; 

Object.c

void Object::MoveTo(double speed, Point position = initPos) 
{ 
    currPos = postion; 
} 

Point.h

class Point 
{ 
    ... 

    private: 
     double x; 
     double y; 
     double z; 
}; 
+1

आपका प्रश्न मुझे अंडे बना यह एक: http://stackoverflow.com/questions/9286801/valid-expressions-for-default-function-arguments –

उत्तर

30

किसी सदस्य फ़ंक्शन के लिए डिफ़ॉल्ट तर्क अभिव्यक्ति केवल कक्षा या वैश्विक दायरे में मौजूद चीज़ों पर निर्भर हो सकती है। डिफ़ॉल्ट तर्क को विधि की घोषणा में भी निर्दिष्ट किया जाना चाहिए (यानी हेडर फ़ाइल में)।

इसके आसपास पाने के लिए, आपको अपनी MoveTo विधि के 2 अधिभार की आवश्यकता है। एक जो 1 तर्क लेता है, और दूसरा जो 2 तर्क लेता है। 1 तर्क लेने वाली विधि अन्य विधि को कॉल करती है, जो उस मान के साथ गुजरती है जिसे आप डिफ़ॉल्ट मानते हैं।

void Object::MoveTo(double speed) 
{ 
    MoveTo(speed, initPos); 
} 

void Object::MoveTo(double speed, Point position) 
{ 
    // Everything is done here. 
} 

नोट है कि जब आप MoveTo(double) कॉल MoveTo(double, Point) बनाने के लिए, यह आप केवल एक बार MoveTo के कार्यान्वयन लिखने के लिए, जिससे DRY सिद्धांत का सम्मान अनुमति देता है।

+0

धन्यवाद! मुझे पता है कि मैं इसे इस तरह से कर सकता हूं। मैं बस सोच रहा था कि ऐसा करने का एक छोटा रास्ता है, जैसे इसे डिफ़ॉल्ट तर्क बनाना। लेकिन मुझे लगता है कि ऐसा करने का यही एकमात्र तरीका होगा। – tuzzer

+0

फिर क्या होगा, केवल एक वैकल्पिक तर्क के बजाय, मेरे पास उनमें से कई हैं? शून्य ऑब्जेक्ट :: MoveTo (डबल स्पीड, प्वाइंट स्थिति = initPos, प्वाइंट ए = एम_ए, प्वाइंट बी = एम_बी, प्वाइंट सी = एमक्यू) तो मुझे कई फ़ंक्शन नहीं करना चाहिए ??? – tuzzer

+0

@MatthewChan: दुर्भाग्य से, हाँ। कई तर्क पारित करने के बजाय, शायद आप डिज़ाइन बदल सकते हैं ताकि उपयोगकर्ता ऑब्जेक्ट पास कर सके।इस ऑब्जेक्ट में पहले से ही उचित डिफ़ॉल्ट होंगे, और उपयोगकर्ता केवल उन लोगों को बदल देगा जिन्हें अलग होना चाहिए। यदि आप इसे इस तरह से करने का निर्णय लेते हैं, तो आपको कई पैरामीटर को अधिक संक्षिप्त (http://en.wikipedia.org/wiki/Method_chaining) सेट करने के लिए विधि चेनिंग मुहावरे में रुचि हो सकती है। –

10

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

समस्या को हल करने के लिए, अन्य उत्तरों में सुझाए गए अनुसार जंजीर ओवरलोड का उपयोग करें।

+0

धन्यवाद। मैंने जनता में initPos को बदलने की कोशिश की, लेकिन जैसा कि आपने कहा, यह अभी भी काम नहीं करेगा। तो क्या यह केवल डिफ़ॉल्ट तर्क के रूप में निरंतर उपयोग कर सकता है (जैसे सदस्य फ़ंक्शन नहीं, कुछ जिसे आप टाइप कर सकते हैं) ?? – tuzzer

1

आप इस तरह अपने कार्य सदस्य ओवरलोड कर सकते हैं:

void Object::MoveTo(double speed, Point position) { 
    .... 
} 

void Object::MoveTo(double speed) { 
    Point position = this->initPos; 

    MoveTo(speed, position); 
} 
+0

दुर्भाग्य से काम के आसपास एकमात्र काम काम कर सकता है, हालांकि बदसूरत लग रहा है :( – Argento

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