2010-03-31 6 views
7

में प्रत्येक विधि कॉल के लिए कुछ कोड निष्पादित करना मेरे पास एक सी ++ कक्षा है जिसका मैं निरीक्षण करना चाहता हूं। इसलिए, मैं सभी विधियों को अपने पैरामीटर और रिटर्न प्रिंट करना चाहता हूं, बस बाहर निकलने से पहले।सी ++

उत्तरार्द्ध कुछ हद तक आसान दिखता है। अगर मैं(), वापसी सब कुछ के लिए क्या कोई मैक्रो

#define return(a) cout << (a) << endl; return (a) 

यह करना होगा (गलत हो सकता है) अगर मैं सभी रिटर्न padronize parenthesized लिए (या जो भी इस बुलाया जा सकता है)। अगर मैं इसे बाहर ले जाना चाहता हूं, तो बस परिभाषित करें।

हालांकि, प्रिंटिंग इनपुट अधिक कठिन लगता है। सी ++ संरचनाओं या वर्कअराउड हैक के साथ, क्या मैं इसे कर सकता हूं?

+4

क्या कोई कारण है कि आप केवल डीबगर का उपयोग नहीं कर सकते हैं? – tloach

+0

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

उत्तर

4

हालांकि, प्रिंटिंग इनपुट अधिक मुश्किल लगता है। क्या कोई तरीका है कि मैं इसे कर सकता हूं, सी ++ संरचनाओं का उपयोग कर या वर्कअराउड हैक के साथ?

सं


अद्यतन: मैं सुझाव दे आप शायद प्राप्त कर सकते हैं कि क्या आप Design by Contract लगाने से जरूरत के आधार पर अपने जवाब में कुछ terseness कम करने के लिए जा रहा हूँ।

+2

छोटे, मीठे, बिंदु पर, सही। +1। एओपी टिप के लिए –

2

ऐसा लगता है जैसे आप मुझे डीबगिंग उपयोगिता का उपयोग करना चाहते हैं। इससे आपको उन सभी पैरामीटर को देखने की अनुमति मिल जाएगी जो आप चाहते हैं।

+0

मैं पैरामीटर देखना नहीं चाहता हूं। मैं कुछ अलग करने के लिए उन सभी को आउटपुट करना चाहता हूं, जैसे एक सांख्यिकीय अध्ययन, आदि, जो उपयोगिता का हिस्सा नहीं है। –

1

यदि आपकी विधियां सभी virtual हैं, तो आप इसे बहुत ही सुरुचिपूर्ण तरीके से प्राप्त करने के लिए decorator-pattern का उपयोग कर सकते हैं।

संपादित करें: उपरोक्त आपकी टिप्पणी से (आप आंकड़ों के लिए आउटपुट चाहते हैं) मैं निष्कर्ष निकालता हूं कि आपको निश्चित रूप से सजावटी-पैटर्न का उपयोग करना चाहिए। यह इस तरह की चीजों के लिए है।

+0

सबक्लासिंग इस स्थिति में वही हासिल करेगा, है ना? हालांकि यह वह नहीं है जिसे मैं ढूंढ रहा हूं! सजाने और उप-वर्गीकरण दोनों को गंदे चाल (हर जगह प्रिंट डालने) की तुलना में कोड की एक ही मात्रा की आवश्यकता होगी। हालांकि, मुझे कॉलर कोड भी बदलना होगा। –

+0

ठीक है, यह आपकी प्रोफ़ाइल में कहता है कि आपको अच्छा डिज़ाइन पसंद है ... अफसोस की बात है, सी ++ में डिज़ाइन पैटर्न को लागू करना हमेशा बॉयलर प्लेट के साथ आता है, लेकिन इसे अभी भी उच्च लचीलापन का लाभ होता है। –

+0

हां, मुझे वास्तव में डिज़ाइन पैटर्न पसंद हैं, गोफ एकमात्र पुस्तक है जो हर बार मेरी मेज पर बैठती है। लेकिन मुझे लगता है कि इस मामले के लिए अधिक है। मैं डेवलपर्स के उद्देश्य के लिए अस्थायी "टर्न-ऑन"/"टर्न-ऑफ" क्षमता चाहता हूं। –

8

कुछ विकल्पों दिमाग में आते हैं:

  • एक डिबगर का प्रयोग करें।
  • decorator pattern का उपयोग करें, जैसा कि Space_C0wb0y ने सुझाव दिया था। हालांकि, यह मैन्युअल टाइपिंग का बहुत कुछ हो सकता है, क्योंकि आपको सजाए गए वर्ग में सभी विधियों को डुप्लिकेट करना होगा और स्वयं को लॉगिंग करना होगा। हो सकता है कि आप अपनी कक्षा पर Doxygen चलाकर सजावट ऑब्जेक्ट के निर्माण को स्वचालित कर सकें और फिर इसके आउटपुट को पार्स कर सकें ...
  • aspect-oriented programming का उपयोग करें। (लॉगिंग, जो आप करना चाहते हैं, एओपी का एक आम अनुप्रयोग है।) Wikipedia lists सी ++: AspectC++, XWeaver, और FeatureC++ के लिए कुछ एओपी कार्यान्वयन।
+0

+1! हालांकि, जो भी मैंने डीबगर का उपयोग करने का सुझाव दिया है और स्पेस_C0wb0y –

+0

सजावट या उप-वर्गीकरण के लिए मुझे कॉलर कोड बदलने के लिए मैंने जो चिंताओं को पढ़ा है, उसे पढ़ें। यहां तक ​​कि इसे करने में सक्षम होने के नाते, मैं नहीं चाहता। इस वर्ग के हर ऑब्जेक्ट के लिए एक सजावटी कॉल डालने की तुलना में परिभाषित करने के साथ-साथ परिवर्तन (#ifdef STATS ... #endif) के साथ परिवर्तन करना बेहतर होता है। –

2

आप हाथ से कुछ कोड डालने से परहेज नहीं करते हैं, तो आप एक वर्ग है कि बना सकते हैं:

  1. लॉग निर्माता
  2. में विधि के लिए प्रवेश मनमाना मापदंडों
  3. डंप करने के लिए एक तरीका प्रदान करता है
  4. नाशक में स्थिति रिकॉर्ड किए गए स्थिति के साथ
  5. लॉग बाहर निकलने के रिकॉर्ड करने के लिए एक तरीका प्रदान करता है

उपयोग कुछ ऐसा दिखाई देगा:

unsigned long long 
factorial(unsigned long long n) { 
    Inspector inspect("factorial", __FILE__, __LINE__); 
    inspect.parameter("n", n); 
    if (n < 2) { 
     return inspect.result(1); 
    } 
    return inspect.result(n * fact(n-1)); 
} 

बेशक, आप निरीक्षक घोषित करने और मानकों का निरीक्षण करने के लिए मैक्रो लिख सकते हैं।

unsigned long long 
factorial(unsigned long long n) { 
    INJECT_INSPECTOR(n); 
    if (n < 2) { 
     return INSPECT_RETURN(1); 
    } 
    return INSPECT_RETURN(n * fact(n-1)); 
} 

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

+0

अच्छा, यद्यपि varargs संभावित मुद्दों में होगा। सी ++ varargs कार्यों के साथ अच्छी तरह से नहीं खेलता है, जिसे अंत में उपयोग करने की आवश्यकता होगी। वे समर्थित हैं, लेकिन वास्तव में केवल सी मूल्यों के लिए। –

+0

मैं 'INJECT_INSPECTOR' के लिए परिवर्तनीय तर्क सूची _macros_ के बारे में सोच रहा था, हालांकि उन्हें आधिकारिक तौर पर C++ में slurped नहीं किया गया है। सी ++ में वर्गास फ़ंक्शन निश्चित रूप से किसी भी वास्तविक तरीके से उपयोग किए जाने के लिए टूटे हुए हैं। मैं प्रत्येक पैरामीटर के लिए एक अलग 'पैरामीटर (नाम, मूल्य)' कॉल का उपयोग करता हूं, कॉलम को कॉल करता हूं, और स्वरूपण के लिए iostreams का लाभ उठाता हूं।मैं आज अभ्यास में समान कुछ उपयोग कर रहा हूं;) –

0

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

+0

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