2010-10-31 19 views
12

यदि सी ++ में मेरे पास कक्षा longUnderstandableName है। उस वर्ग के लिए मेरे पास एक हेडर फ़ाइल है जिसमें इसकी विधि घोषणा है। कक्षा के लिए स्रोत फ़ाइल में, मुझे longUnderstandableName::MethodA, longUnderstandableName::MethodB और इसी तरह, हर जगह लिखना होगा।सी ++: "कक्षा नामस्थान"?

क्या मैं किसी भी तरह से नेमस्पेस या कुछ और उपयोग कर सकता हूं ताकि मैं कक्षा स्रोत फ़ाइल में MethodA और MethodB लिख सकूं, और केवल वहां?

+0

अभी तक, जवाब नहीं है। ** लेकिन ** ... मौजूद है [भाषा में ** 'नेमस्पेस क्लास' ** जोड़ने का प्रस्ताव] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/ 2016/p0223r0.html), जो आप वास्तव में प्राप्त करेंगे, और मैं चाहता हूं: पहले से घोषित वर्ग के सदस्यों की परिभाषा को एक ब्लॉक के भीतर सक्षम करना जो स्वचालित रूप से उन्हें कक्षा में गुंजाइश करेगा - और इस प्रकार कक्षा के नाम के दायरे, टेम्पलेट को निरंतर पुनः टाइप करने से बचें तर्क, इत्यादि। यह विचित्र है कि अब तक इसे लिया गया है और यह अभी भी प्रस्ताव चरण में है, लेकिन यहां हम हैं। आह! मुझे उम्मीद है कि यह इसे सी ++ 20 या जो कुछ भी बनाता है। –

+0

@underscore_d अफसोस की बात है कि उस प्रस्ताव में 'वर्ग का उपयोग करके समकक्ष 'शामिल नहीं है, इसलिए यह अभी भी पूर्ण लचीलापन प्रदान नहीं करता है। – negamartin

+0

@negamartin आप और क्या देख रहे हैं? कृपया एक उदाहरण प्रदान करें। मुख्य बिंदु यह है कि 'नेमस्पेस क्लास' कक्षा के लेखक के लिए इस पुनरावृत्ति को हल करेगी, जो परिप्रेक्ष्य है जिस से ओपी ने इस सवाल से पूछा। इस बीच, वर्ग के उपयोगकर्ता कुछ ऐसा कर सकते हैं जैसे 'tiny_type = someNamespace :: SomeOtherNamespace :: AHugeClassName; '। आपको और क्या चाहिए? –

उत्तर

0

मुझे यकीन है कि मैं द्वारा अनुशंसित नहीं कर रहा हूँ, लेकिन आप की तरह एक मैक्रो इस्तेमाल कर सकते हैं:

#define sn LongUnderstandableName 

void sn::MethodA(parameters) { ... } 
int sn::MethodB(parameters) { ... } 

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

+1

+1, यह एक तेज़ समाधान है, लेकिन मैं इसे भी अनुशंसा नहीं करता। यह आपदा के लिए एक नुस्खा है। –

+1

हां - मुझे संपादक में मैक्रो के रूप में परिभाषित करने की अधिक संभावना होगी, इसलिए मुझे केवल संक्षिप्त नाम टाइप करना होगा, और यह स्वचालित रूप से वास्तविक में विस्तारित हो जाएगा - लेकिन किसी और को इसके बारे में पता होना चाहिए । –

+0

आप इसके बजाए टाइपिफ़ का उपयोग कर सकते हैं। –

0

ठीक है, हाँ, एक बार जब आप नामस्थान समझते हैं।

इसके बजाय अपने वर्ग MyBonnieLiesOverTheOcean नामकरण की

, बजाय निम्नलिखित की स्थापना:

namespace My { namespace Bonnie { namespace LiesOverThe { 
    class Ocean { ... }; 
} } } 

अब, जब आपके तरीकों को परिभाषित करने के लिए, आप एक ही नामस्थान पूरी फ़ाइल के आसपास रखा, और आप लिखते हैं:

Ocean::SomeMethod() ... 

जब बाहर सभी नामस्थान से वर्ग का उपयोग कर, यह है:

My::Bonnie::LiesOverThe::Ocean 

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

+0

यह एक अच्छा विचार है लेकिन यह उन सभी को टाइप करने के लिए चूसना चाहिए :: :) –

+0

ठीक है, यही कारण है कि हमारे पास 'उपयोग' है। – bmargulies

+0

आह ठीक है, हाँ। आप कह सकते हैं 'मेरा :: बोनी :: LiesOverThe' का उपयोग करें; और उसके बाद अंतिम घोंसले स्तर –

1

कक्षाओं के तरीकों के अंदर, आप योग्यता के बिना नाम का उपयोग कर सकते हैं, वैसे भी: longUnderstandableName:: उपसर्ग ड्रॉप करें।

वर्ग स्रोत फ़ाइल है कि तरीकों नहीं कर रहे हैं अंदर कार्यों में, मैं, फ़ाइल-गुंजाइश स्थिर इनलाइन कार्यों को शुरू तो की तरह करने के लिए सुझाव:

inline type MethodA(type param){ 
    return longUnderstandableName::MethodA(param); 
} 

तो फिर तुम MethodA अयोग्य कॉल कर सकते हैं; इनलाइन प्रकृति के कारण, इस संभावना से किसी भी रनटाइम ओवरहेड की लागत नहीं होगी।

+0

हां, लेकिन यह आपको हेडर के अंदर की विधि को परिभाषित करने के लिए मजबूर करता है, जो अक्षम है क्योंकि जब भी वर्ग बदलता है तो यह सभी ग्राहकों के पुनर्मूल्यांकन को मजबूर करता है। –

+1

नहीं, यह आपको ऐसा करने के लिए मजबूर नहीं करता है।वास्तव में, आपको शीर्षलेख में विधि को परिभाषित नहीं करना चाहिए, लेकिन वर्ग स्रोत फ़ाइल के शीर्ष पर - अन्यथा शॉर्टकट वैश्विक रूप से उपलब्ध होगा, जिसे ओपी नहीं करना चाहता। –

+1

केवल स्थिर सदस्यों के लिए काम करता है। – Basilevs

11
typedef longUnderstandableName sn; 

तो फिर तुम के रूप में

void sn::MethodA() {} 
void sn::MethodB() {} 

तरीकों को परिभाषित करने और उन्हें

sn::MethodA(); 
sn::MethodB(); 

का उपयोग यह केवल काम करता है अगर longUnderstandableName एक क्लास का नाम है सकते हैं। यह काम करता है भले ही कक्षा किसी अन्य नामस्थान में गहराई से एम्बेडेड हो।

हैं longUnderstandableName तो नाम स्थान (या स्रोत फ़ाइल) में, एक नाम स्थान का नाम है जहाँ आप तरीकों का उपयोग करना चाहते हैं, तो आप

using namespace longUnderstandableName; 

लिख सकते हैं और उसके बाद

MethodA(); 
MethodB(); 
तरह के तरीकों कॉल

आपको सावधान रहना चाहिए कि using namespace foo; हेडर फ़ाइलों में उपयोग न करें, क्योंकि यह .cpp फ़ाइल को प्रदूषित करता है जिसे हम #include हेडर फ़ाइल में डालते हैं, हालांकि using namespace foo;के शीर्ष पर उपयोग करते हैंफ़ाइल निश्चित रूप से अनुमति और प्रोत्साहित किया जाता है।

+0

क्या यह वास्तव में काम करता है? मेरा मतलब है कि टाइपपीफ घर्षण करने के लिए एक lifesaver है, लेकिन घोषणाओं को आम तौर पर मूल नाम की आवश्यकता होती है। क्या आपने इस दृष्टिकोण का उपयोग किया है? – Basilevs

+0

@ बेसिलव्स: घोषणाओं को मूल नामों की आवश्यकता नहीं है। एक टाइपपीफ "नया प्रकार नहीं बनाता" जो पुराने से अलग होता है - यह सिर्फ एक नया नाम बनाता है जो समान पुराने प्रकार को संदर्भित करता है। लोग कुछ समय में 'std :: map :: iterator' जैसे कुछ अनुवाद करने के लिए हर समय इस दृष्टिकोण का उपयोग करते हैं। (और 'std :: map :: iterator' पहले से ही कुछ वर्ग के लिए 'typedef' है जो एसटीएल में कार्यान्वयन विवरण है। –

+0

लेकिन यह इटरेटर की घोषणा नहीं है। आपने उद्धृत किया है कि इटरेटर द्वारा कहीं और घोषित किया गया है। – Basilevs

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