2013-03-20 6 views
8

मैं एक लॉगिंग/ट्रेसिंग इकाई पर काम कर रहा हूं (और कृपया मौजूदा लोगों को इंगित न करें, यह परिणाम के लिए जितना अधिक अनुभव है)।सी ++ में स्टैक पर बेनामी ऑब्जेक्ट्स?

रन-टाइम कॉलिंग स्टैक ट्रेस प्राप्त करने के लिए, विचार TraceObject उदाहरण बनाना है कि पहली बार एक फ़ंक्शन दर्ज किया गया है, जिसमें वर्तमान वर्ग और फ़ंक्शन की जानकारी होती है। कुछ हद तक समान करने के लिए:

TraceObject to("MyClass", "myClassFunction"); 

TraceObject के निर्माता एक प्रति धागा ढेर पर this धक्का, नाशक इसे फिर से दिखाई नहीं देता। इस प्रकार स्टैक को कॉल स्टैक के लिए पूछताछ की जा सकती है।

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

tl; डॉ

, यह संभव ढेर पर एक गुमनाम, गैर अस्थायी वस्तु बनाने के लिए है (यानी एक ही है कि समारोह रिटर्न जब तक रहते हैं, लेकिन एक पहचानकर्ता नहीं है) और यदि हां, तो यह कैसे किया जाएगा?

+3

मुझे लगता है कि यह सख्ती से संभव है नहीं है, लेकिन किसी मैक्रो और एक अस्पष्ट नाम के साथ, आप एक ही प्राप्त कर सकते हैं। क्या कोई वैध कारण है कि आपको इसे नामहीन होने की आवश्यकता क्यों है या यह "इसकी वास्तव में आवश्यक नहीं" चीज़ है। –

+0

@ कार्तिकटी: हां, एक रैपर मैक्रो सामान्य विचार था। मैं बस सोच रहा था कि क्या मैं "अस्पष्ट" से दूर हो सकता हूं और "अदृश्य" प्राप्त कर सकता हूं। – DevSolar

+0

@ कार्तिक टी बिल्कुल, यह भी है कि लॉग कैसे करता है तो मेरा अनुमान है: – stijn

उत्तर

5

सं

सी ++ में गुमनाम वस्तुओं, temporaries कि भाव के परिणाम हैं कर रहे हैं, लेकिन वे केवल बयान वे में हैं के संदर्भ में रहते हैं।

आप वास्तव में करने का प्रयास करते एक अज्ञात ऑब्जेक्ट घोषित करें, आप पार्सर को भ्रमित करेंगे और आपको लगता है कि आप घोषणा कर रहे हैं ... एक फ़ंक्शन!


लेकिन फिर, क्या यह आवश्यक है?

यदि आप वास्तव में TraceObject घोषित करने के लिए मैक्रोज़ का उपयोग करने के लिए स्वीकार करते हैं, तो प्रत्येक ट्रेस के लिए मैक्रो का उपयोग करना उतना आसान है; और इस प्रकार कक्षा और कार्य प्रदान करते हैं। __func__ या समकक्ष का उपयोग करके आप वर्ग का नाम और फ़ंक्शन नाम निकाल सकते हैं (आवश्यक स्ट्रिंग पार्सिंग का बिट, कंपाइलर पर निर्भर करता है) और वहां से काम करता है।

और निश्चित रूप से, आप प्रत्येक ट्रेस के लिए मैक्रो का उपयोग करेंगे, क्योंकि आप शायद फ़ाइल का नाम और लाइन नंबर चाहते हैं!

+0

आप कॉन्स्ट संदर्भ के साथ अस्थायी वस्तु के लाइव समय को बढ़ा सकते हैं, लेकिन स्वयं को संदर्भित करना अस्थायी वस्तु का एक और नाम है: कॉन्स्ट टी एंड आर = टी(); – AnatolyS

+0

@ एनाटोलीज़: कॉन्स्ट-रेफरेंस या रैवल्यू-रेफरेंस (सी ++ 11 में), लेकिन हां, जैसा कि आपने नोट किया है, वैसे भी यह एक पहचानकर्ता पेश करता है। –

+0

मुझे '__func__' पसंद नहीं है क्योंकि यह कार्यान्वयन परिभाषित है। लेकिन आपको वास्तव में प्रश्न का उत्तर देने के लिए चेकमार्क मिलता है, चाहे अज्ञात वस्तुएं संभव हों ("संख्या")। ;-) – DevSolar

3

जैसा कि मैंने अपनी टिप्पणी में कहा है, सीमित अज्ञात चर का उपयोग नहीं किया जा सकता है।

#define BEGIN_LOG TraceObject abcdefghij("", __func__); 

void Function(){ 
    BEGIN_LOG; 

    //bla bla 

} 

यह करना चाहिए, बशर्ते क्लास नाम प्राप्त करने के लिए एक कंपाइलर मैक्रो है।

संपादित करें: कक्षा नाम प्राप्त करने के लिए एक आसान तरीका के साथ कोई भाग्य नहीं है, आपको Class name macro पर सुझाए गए कुछ की तरह कुछ करना पड़ सकता है। या बस __FILE__ के साथ करें।

संपादित करें: आप __func__ और __FUNCTION__ को आजमा सकते हैं या नहीं, यह देखने के लिए कि क्या आप दोनों या दोनों काम करना चाहते हैं। न तो सी ++ मानक निर्दिष्ट हैं।

+0

AFAIK, '__func__' सी ++ मानक में नहीं है, सिर्फ सी। या क्या यह सी ++ 11 के साथ बदल गया है? – DevSolar

+0

@ डेवसोलर न तो __FUNCTION__ है मेरा मानना ​​है? कोई विचार जो बेहतर समर्थित है? –

1

कुछ लाइन नंबर सामान:

#define XPASTE(arg1, arg2) PASTEX(arg1, arg2) 
#define PASTEX(arg1, arg2) arg1 ## arg2 
#define TRACELOG() \ 
      TraceObject XPASTE(trace_object, __LINE__) 
+0

'__LINE__' जोड़कर जीतने के लिए बहुत अधिक परेशानी नहीं है, लेकिन कम से कम आप दूसरी 'TraceObject' बनाई गई है, तो चेतावनी से" चेतावनी "से बचें। .. – DevSolar

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