2012-05-08 15 views
20

मैं जावा डेवलपर हूं और मैं सी ++ में काफी नया हूं। मुझे किसी प्रकार की उपयोगिता वर्ग को लागू करने की आवश्यकता है, और मैं विधियों को स्थिर के रूप में लागू करने की सोच रहा था। हालांकि, मैं this stackoverflow question पर नामस्थान फ़ंक्शन बनाम स्थैतिक विधि के बारे में आया, और अपर्याप्त नामस्थान फ़ंक्शंस को पसंदीदा दृष्टिकोण माना जाता है। इसलिए यदि नामस्थान फ़ंक्शन को कार्यान्वित करने के तरीके पर कोई आलेख या उदाहरण है तो मैं यह जानना चाहता हूं। उदा।, मुझे हेडर फ़ाइल में नेमस्पेस फ़ंक्शंस को कैसे घोषित करना चाहिए? क्या शीर्षलेख में केवल वर्ग शीर्षलेख फ़ाइल जैसी फ़ंक्शन परिभाषाएं होनी चाहिए और कार्यान्वयन सीपीपी फ़ाइल में होना चाहिए, या क्या मुझे सीधे हेडर फ़ाइल में फ़ंक्शंस को कार्यान्वित करना चाहिए?सी ++ नेमस्पेस फ़ंक्शंस

असल में, मैं एक पाठ फ़ाइल को पार्स करने के लिए किसी एप्लिकेशन को लागू करने का प्रयास कर रहा हूं जिसमें कुछ आदेश शामिल हैं। तो मैं पाठ प्रसंस्करण को संभालने के लिए स्थिर सहायक विधियों को लागू करने के बारे में सोच रहा हूं। E.g पढ़ें कमांड (स्ट्रिंग लाइन)। अगर मैं गलत दिशा में हूं तो कृपया मुझे बताएं। धन्यवाद

+1

सी ++ कार्य करता है और वर्गों के बीच एक बहुत तेज भेद ड्रॉ । यह आपके प्रश्न से स्पष्ट नहीं है जिसे आप उपयोग करने में रुचि रखते हैं। – Shep

+0

हाय शेप, टिप्पणी के लिए धन्यवाद। मैंने अपने प्रश्न के लिए और विवरण जोड़ा। क्या यह आपके प्रश्न का उत्तर देता है? –

उत्तर

19

मुझे हेडर फ़ाइल में नेमस्पेस फ़ंक्शंस को कैसे घोषित करना चाहिए?

namespace MON { 
// extern: 
t_ret func(const t_param& pValue); 
// 'inline': 
inline t_ret inline_func(const t_param& pValue) { ... } 
} // << MON 

हेडर चाहिए केवल वर्ग हेडर फाइल और कार्यान्वयन cpp फ़ाइल में होना चाहिए की तरह कार्यशील परिभाषाएँ होते हैं, या मैं सीधे हेडर फाइल में कार्यों को लागू करना चाहिए?

यह इस बात पर निर्भर करता है कि आप उन्हें (संभावित रूप से) रेखांकित या निर्यात करना चाहते हैं या नहीं। यह निर्भरता को कम करने के लिए अक्सर नीचे आता है।

निर्यात या इनलाइन किए जाने वाले पर विस्तार करने के लिए:

आप अक्सर ग में निर्भरता को कम करने के निर्वासन समारोह के पक्ष में था ++।

file.hpp

namespace MON { 
// extern: 
t_ret func(const t_param& pValue); 
} // << MON 

असम्भव

#include "hefty_stuff.hpp" 

MON::t_ret MON::func(const t_param& pValue) { ... } 

हालांकि, इसके लिए महत्वपूर्ण समय में है: यह एक वर्ग विधि में घोषणा से परिभाषा को अलग करने के बराबर है कुछ मामलों में दिखाई देने की परिभाषा, अक्सर प्रदर्शन के लिए या जब आप आकार जानते हैं तो महत्वपूर्ण है और शीर्षलेख में कई जगह शामिल नहीं हैं। इस प्रकार, inline संस्करण भी एक विकल्प है।

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

निर्यात की गई परिभाषाओं के साथ, आप चुनिंदा रूप से अपनी शामिल निर्भरताओं को प्रतिबंधित (या संगरोध) कर सकते हैं। file.hpp में फ़ंक्शंस का उपयोग करने के लिए शीर्षलेख में नहीं होना चाहिए।


मूल रूप से, मुझे लगता है कि कुछ आदेश होता है एक पाठ फ़ाइल को पार्स करने के लिए एक आवेदन को लागू करने की कोशिश कर रहा हूँ। तो मैं पाठ प्रसंस्करण को संभालने के लिए स्थिर सहायक विधियों को लागू करने के बारे में सोच रहा हूं।

अच्छी तरह से, static से बचा जाना चाहिए। सी ++ एक परिभाषा-नियम का उपयोग करता है। static के परिणामस्वरूप बहुत सारी अनावश्यक प्रतियां होंगी।

namespace { 
t_ret func(const t_param& pValue) { ... } 
} // << anon 

टिप्पणी: गुमनाम नामस्थान भी अनावश्यक प्रतियां में हो सकता है इसके अलावा, एक गुमनाम नाम स्थान C++ सी के static कार्य करने के लिए दृष्टिकोण है। एक स्थिर कार्य के लिए एक विकल्प के रूप में आप उनका उपयोग करने का कारण यह है कि यदि आप एक परिभाषा-नियम से विचलित होना चाहते हैं, और प्रतीक को उस दायरे में घोषित नहीं करना चाहते हैं जिसे 'हल किया जा सकता है'।


अंतिम बिंदु template<> घोषणाओं का संबंध है। टेम्पलेट्स के साथ, जब तक आपका कंपाइलर बाहरी टेम्पलेट का समर्थन नहीं करता तब तक परिभाषा दिखाई देनी चाहिए। टेम्पलेट्स के लिए, आप कई तरीकों से परिभाषा दृश्यता को पूरा कर सकते हैं। आम तौर पर, लोग बस परिभाषा को परिभाषित करेंगे, या परिभाषाओं के लिए एक शीर्षलेख जोड़ देंगे जो हेडर के अंत में या आवश्यकतानुसार शामिल है। टेम्पलेट्स के साथ, कई परिभाषा त्रुटियों से बचने के लिए कार्यों को inline घोषित करने की आवश्यकता नहीं है।

+0

बहुत बहुत जस्टिन धन्यवाद। क्या आप "संभावित रूप से रेखांकित या निर्यात" बिंदु पर थोड़ी अधिक व्याख्या कर सकते हैं, या मुझे कुछ लेख बता सकते हैं कि मुझे इसे एक बोउट पढ़ना चाहिए? –

+2

@KHein yup - विस्तारित – justin

+0

@ जस्टिन, आप templated कार्यों के बारे में उल्लेख करना भूल गए। – Griwes

1

मुझे हेडर फ़ाइल में नेमस्पेस फ़ंक्शंस कैसे घोषित करना चाहिए?

namespace YourNamespace 
{ 
    void fun1(); 
    void fun2(); 
} 

केवल शीर्षक चाहिए वर्ग हेडर फाइल और कार्यान्वयन cpp फ़ाइल में होना चाहिए की तरह कार्यशील परिभाषाएँ होते हैं, या मैं सीधे हेडर फाइल में कार्यों को लागू करना चाहिए?

यदि नामस्थान में आपके कार्य स्थिर हैं, तो आप हेडर फ़ाइल में फ़ंक्शंस को कार्यान्वित कर सकते हैं, या आपको cpp फ़ाइल में कार्यान्वित करना होगा।

+0

पूरी तरह से सही नहीं है, आप शीर्षलेख में गैर स्थैतिक कार्यों को लागू कर सकते हैं। – juanchopanza

+1

@juanchopanza: केवल तभी जब आप उन्हें 'इनलाइन' घोषित करते हैं। –

+0

@ केरेक एसबी: –

12

आप शीर्षक में कार्यों की घोषणा कर सकते हैं:

namespace A { 
    void foo(); 
} 

और सीपीपी में लागू:

namespace A { 
    void foo() { std::cout << "foo!"; } 
} 

तुम भी शीर्षक में कार्यान्वयन डाल सकते हैं, यह inline घोषित करने के लिए सुनिश्चित करने के one definition rule तोड़ने से बचने के लिए:

namespace A { 
    inline void foo() { std::cout << "foo()!"; } 
} 

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

यह शीर्षक में या एक फ़ाइल शीर्षक से शामिल में टेम्पलेट कार्यों का कार्यान्वयन डाल करने के लिए बहुत महत्वपूर्ण है, इन सीपीपी में नहीं जा सकते:

namespace B { 
    template <class T> 
    inline void foo(const T& t) { std::cout << t.name() << "\n"; } 
} 
+0

+1। जब तक आपका कंपाइलर बाहरी टेम्पलेट का समर्थन नहीं करता तब तक परिभाषा दिखाई देनी चाहिए। – milesma

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