2012-05-30 11 views
54

दो स्रोत फ़ाइलों की एक जोड़ी पर विचार करें: एक इंटरफ़ेस घोषणा फ़ाइल (*.h या *.hpp) और इसकी कार्यान्वयन फ़ाइल (*.cpp)।सी ++: नेमस्पेस - शीर्षलेख और स्रोत फ़ाइलों में सही तरीके से उपयोग कैसे करें?

*.h फ़ाइल की तरह हो निम्नलिखित:

namespace MyNamespace { 
    class MyClass { 
    public: 
    int foo(); 
    }; 
} 

मैं स्रोत फ़ाइलों में नामस्थान उपयोग करने के लिए दो अलग-अलग प्रथाओं को देखा है:

*.cpp दिखा # 1 अभ्यास:

#include "MyClass.h" 
using namespace MyNamespace; 

int MyClass::foo() { ... } 

*.cpp अभ्यास दिखा रहा है # 2:

मेरा प्रश्न: क्या इन दो प्रथाओं के बीच कोई अंतर है और क्या दूसरे की तुलना में बेहतर माना जाता है?

+23

वहाँ भी विकल्प 3 है : बस हमें पूरा नाम, उदाहरण के लिए 'int MyNamespace :: MyClass :: foo() ...'। –

+1

संभावित डुप्लिकेट: http://stackoverflow.com/questions/7789163/using-directive-best-practice – David

+0

@ डुप्लिकेट न करें। ये प्रश्न एक दूसरे के पूरक हैं। इस सवाल के लिए डेव द्वारा दिए गए लिंक को "पढ़ने के लिए ..." के रूप में जोड़ने की अनुशंसा करें। मेरा सवाल नौसिखियों को सही शैली चुनने में मदद करेगा। – DaddyM

उत्तर

42

एक कोड पठनीयता दृष्टिकोण से, यह शायद इस कारण के लिए # 2 विधि का उपयोग करने मेरी राय में बेहतर है:

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

+0

धन्यवाद। बहुत साफ़। एक और जवाब के लिए थोड़ा इंतजार करेंगे। – DaddyM

+0

प्रश्न डेव आपके प्रश्न पर अपनी टिप्पणी में जुड़ा हुआ प्रश्न भी –

+0

दोस्तों पर देखे गए दो तरीकों के बीच अंतर (यदि कोई है) में कुछ महत्वपूर्ण बिंदुओं को रेखांकित करता है, मुझे वास्तव में नहीं पता कि किसका चयन करना है। एक-दूसरे के पूरक होने पर उनके पास छेड़छाड़ होती है। – DaddyM

36
स्पष्ट

है विकल्प आपको दिखाई नहीं दिया घोषित करने के लिए अनुमति देता है:

int MyNamespace::MyClass::foo() 
{ 
    // ... 
} 

यह भी बहुत verbose है; ज्यादातर लोगों के लिए बहुत अधिक है। चूंकि using namespace नाम विवादों के लिए एक प्राप्ति है, कम से कम मेरे अनुभव में, और बहुत सीमित क्षेत्रों और स्थानों को छोड़कर टालना चाहिए, I आम तौर पर आपके # 2 का उपयोग करते हैं।

+2

धन्यवाद बहुत स्पष्ट है। साथ में हमने नामस्थान उपयोगकर्ताओं के लिए एक अच्छा FAQ पृष्ठ बनाया है। :) – DaddyM

+0

दोस्तों, मैं वास्तव में नहीं जानता कि किसके चयन का जवाब है। एक-दूसरे के पूरक होने पर उनके पास छेड़छाड़ होती है। – DaddyM

4

इन दोनों प्रथाओं

हाँ के बीच कोई अंतर है। # 1 और # 2 क्रमश: using-directive और namespace definition के उदाहरण हैं। वे इस मामले में प्रभावी रूप से समान हैं लेकिन अन्य परिणाम हैं।

# 1::

using namespace MyNamespace; 
int x; // defines ::x 

# 2:

namespace MyNamespace { 
    int x; // defines MyNamespace::x 
} 

एक से बेहतर माना जाता है उदाहरण के लिए, यदि आप MyClass::foo के साथ एक नया पहचानकर्ता परिचय, यह एक अलग गुंजाइश होगा अन्य?

# 1 पेशेवर: थोड़ा और अधिक; आकस्मिक रूप से MyNamespace में अनजाने में कुछ प्रस्तुत करना कठिन है। विपक्ष: अनजाने में मौजूदा पहचानकर्ताओं को खींच सकता है।

# 2 पेशेवर: अधिक स्पष्ट है कि मौजूदा पहचानकर्ताओं की परिभाषाएं और नए पहचानकर्ताओं की घोषणाएं MyNamespace से संबंधित हैं। विपक्ष: अज्ञात रूप से MyNamespace पर पहचानकर्ताओं को परिचय देना आसान है।

# 1 और # 2 दोनों की आलोचना यह है कि वे शायद पूरे नामस्थान का जिक्र कर रहे हैं जब आप शायद MyNamespace::MyClass के सदस्यों की परिभाषा की परवाह करते हैं। यह भारी हाथ है और यह इरादे को खराब तरीके से संवाद करता है।

# 1 के लिए एक संभावित विकल्प के एक using-declaration जो केवल पहचानकर्ता में आपकी रुचि है शामिल हैं:

#include "MyClass.h" 
using MyNamespace::MyClass; 

int MyClass::foo() { ... } 
2

मैं भी जोड़ने के लिए है कि यदि आप किसी कारण के कारण फैसला एक टेम्पलेट लागू करना चाहते हैं एक cpp फ़ाइल में विशेषज्ञता और बस using namespace पर भरोसा करते हैं तो आपको निम्न समस्या में पड़ जाएगा:

// .h file 
namespace someNameSpace 
{ 
    template<typename T> 
    class Demo 
    { 
     void foo(); 
    }; 
} 

// .cpp file 
using namespace someNameSpace; 

template<typename T> 
void Demo<T>::foo(){} 

// this will produce 
// error: specialization of 'template<class T> void someNameSpace::Demo<T>::foo()' in different namespace [-fpermissive] 
template<> 
void Demo<int>::foo(){} 

अन्यथा यदि आप # 2 विधि लागू इस ठीक हो जाएगा।

0

मैं एक और तरीका जोड़ने के लिए, का उपयोग कर करना चाहते हैं का उपयोग कर-घोषणा:

#include "MyClass.h" 
using MyNamespace::MyClass; 

int MyClass::foo() { ... } 

इस तरह नाम स्थान नाम कई बार टाइपिंग से बचाता है अगर वर्ग कई कार्य होते हैं