2008-12-09 6 views
9

मेरी कक्षा कक्षा में सभी सदस्य चर और सदस्य कार्य स्थिर हैं।कक्षा के निर्माण को रोकें जिनके सदस्य कार्य सभी स्थिर हैं

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

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

धन्यवाद

+0

यह सी ++ है, जावा नहीं! स्थिर कार्यों को रखने के लिए आपको कक्षा बनाने की आवश्यकता क्यों है? क्लास – hasen

+2

के बजाय उन्हें वैश्विक, या नामस्थान {} के नीचे बनाएं क्योंकि यदि आप इसके बजाय नामस्थान का उपयोग करते हैं, तो आपके पास निजी स्टेटस रखने के लिए निजी स्थिर सदस्य नहीं हो सकते हैं। –

+0

निश्चित रूप से आप कर सकते हैं! उन्हें स्थिर बनाओ और वे उस संकलन इकाई के बाहर उपलब्ध नहीं होंगे। – Ferruccio

उत्तर

10

अन्य लोगों की तरह कहा, एक namespace आप क्या इस्तेमाल करना चाहिए है। यदि आप अपने वर्ग के साथ रहने के एक वर्ग के लिए एक निजी निर्माता है कि बनाने के लिए, और इसे से प्राप्त करने के लिए चाहते हैं, तो अपने इरादे स्पष्ट बनाने के लिए:

class NonConstructible { 
    NonConstructible(); 
}; 

class SuperUtils: NonConstructible { 
    static void foo(); 
    // ... 
    static std::vector<int> globalIDs; 
    // ... 
}; 

ठीक है, अब के नाम स्थान जो कर रहे हैं पर गौर करते हैं एक और एक ही तरीका है यह करने के लिए:

namespace SuperUtils { 
    void foo() { 
     // .... 
    } 

    std::vector<int> globalIDs; 
}; 

आप कॉल कर सकते हैं कि दोनों ही मामलों में SuperUtils::foo(); का उपयोग कर, लेकिन नाम स्थान लाभ यह है कि एक दायरे में आप नाम स्थान घोषणा और निर्देश का उपयोग कर सकते कुछ लाने के लिए है या में सभी सदस्यों वर्तमान दायरा, ताकि आप वें संदर्भित कर सकें SuperUtils:: का उपयोग किए बिना उन्हें:

void superFunction() { 
    using namespace SuperUtils; 
    foo(); 
} 

आम तौर पर उस से बचा जाना चाहिए है, यह सहायक होता है जब विधि SuperUtils, तो कोड की पठनीयता में सुधार कर सकते हैं, जो विशेष रूप से ज्यादा सामान का उपयोग कर रहा हो सकता है।

+0

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

+0

दोनों में से सर्वश्रेष्ठ प्राप्त करने के लिए, आप ग्लोबल्स को कक्षा में डाल सकते हैं, फिर गैर-सदस्य मित्र कार्य उन्हें एक्सेस करने के लिए कर सकते हैं। या कक्षा में ग्लोबल्स और फ़ंक्शंस डालें, फिर कक्षा के दायरे को निर्दिष्ट किये बिना उन्हें कॉल करने के लिए नामस्थान में इनलाइन फ्री फ़ंक्शंस रखें। –

+0

"पहले यह निजी था" - क्षमा करें, मेरा मतलब है कि पहले यह निजी हो सकता है। प्रश्नकर्ता ने यह नहीं कहा था कि यह था। –

11

एक निजी डिफ़ॉल्ट कन्स्ट्रक्टर बनाना पर्याप्त होना चाहिए। अन्य सभी डिफ़ॉल्ट संरचनाएं (कॉपी कन्स्ट्रक्टर और असाइनमेंट) दोनों सही ढंग से काम करने के लिए एक उदाहरण होने पर भरोसा करते हैं। यदि कोई डिफ़ॉल्ट कन्स्ट्रक्टर नहीं है तो उदाहरण बनाने का कोई तरीका नहीं है, इसलिए वास्तव में प्रतिलिपि निर्माण भाग को प्राप्त करने का कोई तरीका नहीं है।

यह संभावना है कि आप कुछ सिर दर्द हालांकि निजी और कार्यान्वित नहीं के रूप में सभी 3 को परिभाषित करने की बचत होगी।

+0

एक बार फिर, नीचे मतदान किया गया क्योंकि ... – JaredPar

+2

यह होना चाहिए: घोषित करें लेकिन कन्स्ट्रक्टर को परिभाषित नहीं करें (कार्यान्वित करें)। यह एक बाहरी कोड बनाने की कोशिश कर रहे बाहरी कोड का ख्याल रखेगा (कन्स्ट्रक्टर निजी है) और आंतरिक कोड गलती से ऑब्जेक्ट बना रहा है: कन्स्ट्रक्टर के रूप में लिंकर त्रुटि परिभाषित नहीं है। –

3

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

20

इसके बजाय, आप बिना आधार के एक अलग नाम स्थान में कार्य तरीकों बनाने से बेहतर हो सकता है। कॉल वाक्य रचना ही होगा:

बजाय namespace::function()classname::function()

और आप किसी को अपने वर्ग का दृष्टांत की कोशिश कर रहा से निपटने के लिए की जरूरत नहीं है।

+0

सभी स्थिर तरीकों के साथ कक्षा रखने से निश्चित रूप से काफी बेहतर है। – Naveen

+1

मैं दृढ़ता से असहमत हूं। मैं 'नेमस्पेस Xxxx का उपयोग कर लिख सकता हूं;' और फिर मुझे 'Xxxx :: Symbol' लिखना नहीं होगा - बस 'प्रतीक' पर्याप्त है। स्थैतिक वर्ग दृष्टिकोण प्रोग्रामर को हर बार 'कक्षा :: प्रतीक' टाइप करने के लिए मजबूर करता है। – xxbbcc

0

गैर ढेर ऑब्जेक्ट के निर्माण को रोकने के लिए सबसे अच्छा तरीका है नाशक निजी बनाने के लिए है। तब कोई भी तरीका नहीं है जब कंपाइलर ऑब्जेक्ट को नष्ट कर सकता है जब यह दायरे से बाहर हो जाता है और यह शिकायत करेगा। यह किसी को भी नया करने से नहीं रोकेगा।

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