2008-12-23 18 views
5

चलो एक सी ++ कक्षा पर विचार करें। निष्पादन की शुरुआत में मैं एक एक्सएमएल फ़ाइल से मूल्यों का एक सेट पढ़ना चाहता हूं और उन्हें इस कक्षा के डेटा सदस्यों में से 7 को असाइन करना चाहता हूं। वे मूल्य पूरे निष्पादन के दौरान नहीं बदलते हैं और उन्हें कक्षा के सभी वस्तुओं/उदाहरणों द्वारा प्रश्न में साझा किया जाना है। क्या स्थिर डेटा सदस्य इस व्यवहार को प्राप्त करने का सबसे शानदार तरीका हैं? (बेशक, मैं वैश्विक चर पर विचार नहीं करता)क्या मुझे स्थिर डेटा सदस्यों का उपयोग करना चाहिए? (सी ++)

उत्तर

3

मुझे स्थिर चर के अच्छे उपयोग की तरह लगता है। आप चर के मुकाबले निश्चित पैरामीटर के रूप में इनका अधिक उपयोग कर रहे हैं, और मूल्यों को वैध रूप से साझा करने की आवश्यकता है।

3

स्थिर सदस्य यहां काम करेंगे और पूरी तरह से स्वीकार्य हैं। एक और विकल्प कक्षा के लिए singleton pattern का उपयोग करना है जो इन सदस्यों को यह सुनिश्चित करने के लिए रखता है कि वे केवल एक बार निर्मित/सेट हैं।

5

जैसा कि अन्य ने उल्लेख किया है, इस मामले में स्थिर सदस्यों का उपयोग उचित लगता है। बस याद रखें कि यह मूर्खतापूर्ण नहीं है; वैश्विक डेटा के साथ मुद्दों में से कुछ स्थिर सदस्यों के लिए लागू होते हैं:

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

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

+0

डेविड, वे एक बार जब आप एक्सएमएल ऑब्जेक्ट को स्थिर ऑब्जेक्ट के रूप में रखने का फैसला करेंगे। विनाश का आदेश भी प्रासंगिक है। नीचे मेरा जवाब देखें। –

2

स्थिर वर्ग के सदस्यों के उचित उपयोग की तरह लगता है। बस यह न भूलें कि वे वास्तव में नामस्थान के साथ वैश्विक चर हैं और (शायद) कुछ सुरक्षा। इसलिए, यदि संभावना है कि आपका एप्लिकेशन किसी दिन 'अलग-अलग वातावरण' या कुछ ऐसा विकसित कर सकता है जिसे प्रत्येक के लिए इन ग्लोबल्स के सेट की आवश्यकता होगी, तो आप स्वयं को कोने में चित्रित कर लेते।

रॉब द्वारा सुझाए गए अनुसार, एक सिंगलटन का उपयोग करने पर विचार करें, जो बाद में किसी प्रकार के प्रबंधित वातावरण चर में बदलना आसान है।

3

यह एक साफ डिजाइन नहीं है। स्टेटिक क्लास के सदस्य वैश्विक स्थिति और global state is bad हैं।

यह आपको परेशानी का कारण नहीं बन सकता है यदि यह एक छोटे से मध्यम आकार की परियोजना है और आपके पास स्वचालित परीक्षण के लिए उच्च लक्ष्य नहीं हैं, लेकिन जब से आप पूछते हैं: बेहतर तरीके हैं।

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

इस तरह आपकी कक्षा टेस्टेबल हो जाती है और आपने अपनी चिंताओं को सही ढंग से अलग कर दिया है।

पीएस। Don'tusesingletonseither

+2

जब भी मैं पढ़ता हूं "xxx खराब है", मेरा oversimplification डिटेक्टर फ़्लैशिंग शुरू होता है। अन्य पोस्टर की तरह, मेरा मानना ​​है कि स्थैतिक चर का यह उपयोग पूरी तरह से मान्य है। –

+1

वैश्विक स्थिति मुख्य रूप से खराब होती है यदि यह बदलती है। वैश्विक स्थिति का अपरिवर्तनीय, जो यह है, ठीक काम करता है। –

+0

बस अपना लिंक पढ़ें; यह कहता है कि सिंगलेट्स (और लगभग समकक्ष वैश्विक स्थिति) कुछ भी नुकसान नहीं पहुंचाते हैं यदि उनमें अपरिवर्तनीय डेटा है, जो यह है। –

0

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

मुझे पता चला है कि जब आप अपना कोड डिज़ाइन करते हैं तो परीक्षण लिखने की सोच आपको कोड को अच्छी तरह से फैक्टर और पुन: प्रयोज्य रखने में मदद करती है।

1

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

  1. सभी स्थैतिक वस्तुएं पूरी तरह से किसी भी xml_stuff उदाहरण के निर्माण के बाद पूरी तरह से बनाई गई हैं।
  2. सी ++ में स्थिर वस्तुओं के विनाश का आदेश उनके निर्माण के पूरा होने के ठीक विपरीत है (जब उनके निर्माता निष्पादन को समाप्त करते हैं)।

कोड:

class xml_stuff { 
public: 
    xml_stuff() { 
     // 1. touch all members once 
     // => 2. they are created before used 
     // => 3. they are created before the first xml_stuff instance 
     // => 4. they will be destructed after the last xml_stuff instance is 
     //  destructed at program exit. 
     get_member1(); 
     get_member2(); 
     get_member3(); 
     // ... 
    } 

    // the first time their respective function is called, these 
    // objects will be created and references to them are returned. 
    static type1 & get_member1() { static type1 t; return t; } 
    static type2 & get_member2() { static type2 t; return t; } 
    static type1 & get_member3() { static type1 t; return t; } 
    // ... all other 7 members 
}; 

अब, वस्तुओं xml_stuff द्वारा वापस :: get_memberN() मान्य किसी भी xml_stuff उदाहरण के पूरे जीवन भर, क्योंकि उन के किसी सदस्य किसी भी xml_stuff उदाहरण से पहले का निर्माण किया गया है। सादे स्थैतिक डेटा सदस्यों का उपयोग करके, आप यह सुनिश्चित नहीं कर सकते हैं, क्योंकि अनुवाद इकाइयों में सृजन के क्रम को C++ में अपरिभाषित छोड़ दिया गया है।

2

निष्पादन मैं एक एक्सएमएल फ़ाइल से मानों का एक सेट पढ़ सकते हैं और उन्हें इस वर्ग की डेटा सदस्यों में से 7 को असाइन करना चाहते की शुरुआत में । उन मूल्य पूरे निष्पादन के दौरान नहीं बदलते हैं और उन्हें कक्षा के सभी ऑब्जेक्ट/उदाहरणों द्वारा साझा किया जाना चाहिए।

बोल्डफेस में वाक्य किकर है। जब तक कि कथन धारण करता है, स्थिर चर का उपयोग ठीक है। इसे कैसे लागू किया जाएगा?

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

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