2009-04-21 15 views
12

मैंवैश्विक चर करने के लिए उचित "सी ++ तरीका" क्या है?

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

मैं कुछ भिन्न रूप देखा है, हर जगह मुख्य वर्ग निर्वासन की घोषणा की तरह है, लेकिन यह महसूस नहीं करता है बहुत वस्तु उन्मुख। मुख्य वर्ग में तत्वों को सभी (या अधिकतर) अन्य वर्गों के लिए सुलभ बनाने के लिए "मानक" सी ++ तरीका क्या है?

+3

सी ++ में थ्रेड-सुरक्षा के साथ सिंगलटन को कार्यान्वित करने के बारे में एक दिलचस्प चर्चा इस पेपर में पाई जा सकती है: http://www.aristeia.com /Papers/DDJ%5FJul%5FAug%5F2004%5Frevised.pdf –

उत्तर

12

singleton design pattern का उपयोग करें।

मूल रूप से आप एक वस्तु का एक स्थिर उदाहरण लौट सकते हैं और उपयोग करें कि अपने काम के सभी के लिए।

कृपया इस link about how to use a singleton और भी इस stackoverflow link about when you should not use it

चेतावनी देखें: सिंगलटन पैटर्न वैश्विक राज्य को बढ़ावा देने के शामिल है। वैश्विक कारण कई कारणों से खराब है।
उदाहरण के लिए: इकाई परीक्षण।

+1

लेकिन जागरूक रहें! बुद्धिमानी से अपने सिंगलेट का प्रयोग करें: http://www.ibm.com/developerworks/webservices/library/co-single.html – toxvaerd

+0

यह भी देखें: http://stackoverflow.com/questions/137975/what-is-so-bad- लगभग-सिंगलेट्स – Reunanen

+0

धन्यवाद दोस्तों, मैंने इन 2 लिंक को शामिल करने के लिए अपना उत्तर अपडेट किया। –

0

मुझे लगता है कि Service Locator करेंगे। आपको या तो रचनाकारों में चारों ओर गुज़रना होगा, या कुछ प्रसिद्ध स्थानों में विश्व स्तर पर सुलभ स्थिर सदस्य कार्य करना होगा। पूर्व विकल्प अधिक बेहतर है।

+0

एक सिंगलटन एक और नाम से ... –

7

यह इतना बुरा विचार सभी निर्माताओं को लकड़हारा और config पारित करने के लिए अगर आपके लकड़हारा और config पर्याप्त सार है नहीं है।

सिंगलटन भविष्य में एक समस्या हो सकती है। लेकिन यह परियोजना शुरू में सही विकल्प की तरह seams। आपकी पंसद। यदि आपकी परियोजना काफी छोटी है - सिंगलटन के साथ जाएं। यदि नहीं - निर्भरता इंजेक्शन। अगर यह अपनी स्थिति या नहीं करने में सहायक है

+0

तुम सिर्फ एक फाइल करने के लिए जोड़कर कर रहे हैं इतना बुरा नहीं हो सकता है, लेकिन आप एक प्रवेश ढांचे को प्रारंभ करने के लिए है, तो आप इसे हर बार reinitialize करने के लिए नहीं चाहते हो सकता है। –

+1

पुन: प्रारंभ करें? क्यूं कर? आप शीर्ष पर एक बार बनाते हैं और इसे आवश्यक सभी सेवाओं के लिए नीचे भेज देते हैं। –

+0

क्षमा करें, मैं पढ़ने में भूलना –

0

पता नहीं है, लेकिन MFC में, वहाँ था/एक आवेदन वर्ग है।

मैं इस तरह की चीजों को उस वर्ग में फेंकने के लिए उपयोग करता हूं।

मैं तुम्हें MFC उपयोग नहीं कर रहे मान, लेकिन अगर आप एक आवेदन वर्ग या कुछ इसी तरह है, यह उपयोगी हो सकता है।

0

मैं सिंगलटन पैटर्न से बचूंगा।
परीक्षण की बात आने पर बहुत सारी समस्याएं और सभी (देखें What is so bad about singletons?)

व्यक्तिगत रूप से मैं निर्माता में लॉगजर इत्यादि पास कर दूंगा। वैकल्पिक रूप से आप संसाधन के संदर्भ को बनाने/पास करने के लिए एक कारखाने का उपयोग कर सकते हैं।

+0

उचित रूप से निष्पादित किया गया है, जहां कहीं भी आप अपने # अंतर्निहित, और अपने विकल्पों का उपयोग करते हुए एक सिंगलटन का उपयोग करने के बीच वास्तव में कोई अंतर नहीं रखते हैं, आपके विकल्प को छोड़कर आपको प्रत्येक स्तर पर एक संदर्भ पारित करना होगा। – kmarsh

5

सिस्टम पहले से मौजूद क्यों नहीं है? यही है, एक फ़ाइल में आउटपुट करने के लिए std :: clog को रीडायरेक्ट करें और std :: clog पर लिखें।

std::fstream *f = new std::fstream("./my_logfile.log") 

std::clog.rdbuf(f->rdbuf()); 

std::clog << "Line of log information" << std::endl; 
+0

आप वास्तविक लॉगर के लगातार स्वरूपण (एक स्थान पर परिभाषित) खो देते हैं, और आप संभावित रूप से कुछ गैर-मानक जानकारी (यानी कोई स्ट्रिंग रूपांतरण) आउटपुट करने के लिए उपयोगिता फ़ंक्शन भी खो देते हैं। लेकिन एक छोटी परियोजना के लिए, यह जाने का एक बहुत तेज़ और आसान तरीका है। – rmeador

+1

भले ही आप std :: clog का उपयोग नहीं करना चाहते हैं, फिर भी आप इससे सीख सकते हैं। क्लोग एक वैश्विक चर है। यदि आप अपना खुद का लॉगर चाहते हैं, तो इसे वैश्विक चर बनाएं। – jalf

+0

@jalf: यह वास्तव में आवश्यक होने पर केवल उदाहरण बनाने के लिए "पहले उपयोग पर निर्माण" -Idiom का उपयोग करता है। –

0

log4cxx का प्रयोग क्यों नहीं? ऐसी समस्याएं बहुत पहले हल की जाती हैं और व्यापक रूप से कई लोगों द्वारा उपयोग की जाती हैं। जब तक कि आप अपने स्वयं के कुछ विशेष लॉगिंग सिस्टम का निर्माण नहीं कर रहे हैं ... ऐसे मामले में, मैं फैक्ट्री पैटर्न का उपयोग करूंगा जो रुचि रखने वाले किसी के लिए लॉगर्स बनाएगा (या सिंगलटन होने पर मौजूदा इंस्टेंस को छोड़ देगा)। अन्य वर्ग लॉगर प्राप्त करने के लिए कारखाने का उपयोग करेंगे। कन्स्ट्रक्टर पैरामीटर में पासिंग लॉगर्स एक बुरा विचार है, क्योंकि यह आपकी कक्षा को लॉगर के साथ जोड़ता है।

3

मैं किसी प्रकार के सिंगलटन दृष्टिकोण से सहमत हूं। आप निश्चित रूप से जगह पर चारों ओर लॉगर ऑब्जेक्ट्स पास नहीं करना चाहते हैं। यह बहुत उबाऊ हो जाएगा, और आईएमएचओ सिर्फ एक सादा वैश्विक वस्तु होने की तुलना में एक खराब डिजाइन है।

आपके पास एक अच्छा समाधान है या नहीं, इसके बारे में एक अच्छी परीक्षा है कि इसे आवश्यक फ़ंक्शन में लॉगिंग करने के लिए आवश्यक कदम हैं।

आप ज्यादा

की तुलना में अधिक
#include "Logger.h" 
... 
void SomeFunction() 
{ 
    ... 
    LOGERROR << "SomeFunction is broken"; 
    ... 
} 
... 

तो आप प्रयास बर्बाद कर रहे करने के लिए है।

1

लॉगिंग के रूप में aspect orient programming

आम तौर पर प्रवेश करने में एक समारोह या एक वस्तु के लिए चिंता का विषय नहीं है 'चिंता की जुदाई' के दायरे के अंतर्गत आती है (उदाहरण के लिए, यह वस्तु की स्थिति बदलने नहीं है, यह केवल है राज्य को देखने/रिकॉर्ड करने के लिए एक तंत्र, और आउटपुट अनिवार्य रूप से अधिकांश संदर्भों में डिस्पोजेबल है) यह एक क्षणिक और अक्सर वैकल्पिक साइड फ़ंक्शन है जो किसी वर्ग के संचालन में योगदान नहीं देता है। किसी ऑब्जेक्ट की विधि लॉगिंग कर सकती है, लेकिन लॉगिंग वहां की जा सकती है क्योंकि यह करने के लिए एक सुविधाजनक स्थान है या कोड निष्पादन धारा में वह बिंदु है जहां कोई राज्य को रिकॉर्ड करना चाहता है।

क्योंकि सी ++ पहलुओं को परिभाषित करने के लिए सुविधाएं प्रदान नहीं करता है, इसलिए मैं अनिवार्य रूप से बाह्य अस्थायी वस्तुओं को वैश्विक रूप से लॉगर्स रखने और उन्हें नाम रखने के लिए नामस्थान में लपेटता हूं। नेमस्पेस का उद्देश्य रोकथाम के लिए नहीं है, इसलिए यह बदसूरत है, लेकिन किसी और चीज की कमी के लिए यह सुविधाजनक है और औपचारिक मानकों में लॉगर्स पास करने या उन सभी ऑब्जेक्ट्स में संदर्भित करने से बहुत कम बदसूरत और असंगत है जिन्हें आप लॉग करना चाहते हैं। यह लॉगर को हटाने में भी आसान बनाता है अगर किसी बिंदु पर मैं तय करता हूं कि मुझे अब लॉगर की आवश्यकता नहीं है (यानी अगर इसे केवल डीबगिंग के लिए उपयोग किया जाता है)।

+0

इसी प्रकार, इसे नामस्थान में ग्लोबल होने से बहु-थ्रेडेड ऐप्स के लिए लॉकिंग मेकेनिसिम के आसान कार्यान्वयन की अनुमति मिलती है। –

0

आप अन्य वर्गों है कि आप "सब कुछ"

के लिए उपयोग करना चाहते हैं के निर्माता में अपने मुख्य वर्ग पारित तो फिर तुम लकड़हारा आदि के माध्यम से सदस्य गुण के लिए पहुँच प्रदान कर सकते हैं। (मेरे सी ++ सिंटैक्स को क्षमा करें, यह केवल एक बनाई गई भाषा है जिसे "सी ++ वीबी द्वारा भ्रमित" कहा जाता है)

उदा।

Class App { 
    Private m_logger; 
    Private m_config; 

    Public logger() { 
     return m_logger; 
    } 

    Public config() { 
     return m_config 
    } 
} 

Class Window1 { 
    New(anApp) { 
    } 
    .... 
} 
0

विरासत और बहुरूपता के बारे में कोई भी क्यों नहीं सोचा है? आप उस सिंगलटन के साथ एक अमूर्त कारखाने का भी उपयोग कर सकते हैं;)

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