2010-02-10 26 views
6

मैं एक लकड़हारा वर्ग ऐसा है कि इस तरह की एक कार्यक्षमता के साथ बनाना चाहते हैं:कैसे मैं अदालत शैली इंटरफेस के साथ एक लकड़हारा वर्ग लिख सकता हूँ (लकड़हारा << "त्रुटि:" << वैल << endl;)

Logger log; 
log << "Error: " << value << "seen" << endl; 

यह मुझे एक कस्टम प्रारूपित संदेश मुद्रित करना चाहिए। जैसे "2009/12/09 11:22:33 त्रुटि 5 देखा"

मेरे साधारण क्लास वर्तमान में इस तरह दिखता है:

class Logger { 
    private: 
     ostringstream oss; 
    public: 
     template <typename T> 
     Logger& operator<<(T a); 
} 

template <typename T> 
Logger& Logger::operator<<(T a) { 
    oss << a; 
    return *this; 
} 

void functionTest(void) { 
    Logger log; 
    log << "Error: " << 5 << " seen"; 
} 

यह ओएसएस सही ढंग से बफर "त्रुटि: 5 बार देखा गया" के लिए कारण होगा। लेकिन मुझे नहीं पता कि मुझे कौन सा फ़ंक्शन लिखना/संशोधित करना है ताकि स्क्रीन पर कुछ प्रिंट हो। क्या कोई यह जानता है कि इसे कैसे काम करना है या क्या इस वर्ग को मेरी कार्यक्षमता के काम के लिए डिजाइन करने का कोई और तरीका है?

+0

प्रश्न समाप्त करने के लिए उपयोग करने के लिए बाध्य समाप्त कर रहे हैं:। टाइम स्टैम्प। क्या आप समय स्टाम्प आउट करना चाहते हैं: 1) प्रत्येक अभिव्यक्ति 2) केवल प्रत्येक पंक्ति की शुरुआत में। क्या आप चाहते हैं कि लाइन स्वयं को समाप्त कर दे (आपके फ़ंक्शनटेस्ट() के अनुसार) मूल रूप से आपको थोड़ा और होना चाहिए उन शर्तों के बारे में विशिष्ट है जिनके अंतर्गत टाइम स्टैम्प जोड़ा गया है। क्या आप दोनों को कंसोल फ़ाइल में लॉगिंग कर रहे हैं? आपको एक विशेष कक्षा की आवश्यकता क्यों है और आप मानक स्ट्रीम का उपयोग क्यों नहीं कर सकते? –

+0

मार्टिन, यह केवल नमूना वर्ग है मैंने मूल लॉगर क्लास को कोउट शैली के उपयोग के बारे में केवल मुद्दे के साथ छीन लिया लॉगर का –

उत्तर

1

जहां तक ​​मैं देख सकता हूं कि आपका लॉगर ostringstream से अलग नहीं है। यह केवल लेता है जो इसे दिया जाता है और इसे स्ट्रिंग स्ट्रीम में आउटपुट करता है। यदि आप इसे इस तरह उपयोग करना चाहते हैं, तो आप लॉगर के लिए एक विनाशक लिख सकते हैं जो स्ट्रिंग को स्ट्रिंग आउटपुट करता है।

Logger::~Logger() 
{ 
    std::cout<<getcurrentDateTimeAsString()<<" "<<oss.str()<<std::endl; 
} 

लेकिन निश्चित रूप से, अगर कोई लॉगर * बनाया जाता है और पूरे कार्यक्रम में उपयोग किया जाता है तो इसका कोई अर्थ नहीं होगा।

0

यह (this post से) आप क्या चाहते हैं करता है, लेकिन यह std :: endl साथ प्रत्येक पंक्ति समाप्त करने के लिए आप बलों:

class Logger { 
    private: 
     ostringstream oss; 
    public: 
     template <typename T> 
     Logger& operator<<(T a); 

    Logger& operator<<(std::ostream&(*f)(std::ostream&)) 
    { 
     if(f == std::endl) 
     { 
      std::cout << "12-09-2009 11:22:33" << oss.str() << std::endl; 
      oss.str(""); 
     } 
     return *this; 
    } 
}; 

template <typename T> 
Logger& Logger::operator<<(T a) { 
    oss << a; 
    return *this; 
} 

void functionTest(void) { 
    Logger log; 
    log << "Error: " << 5 << " seen" << std::endl; 
} 

int main() 
{ 
    functionTest(); 
} 

संपादित करें: खैर अपनी टिप्पणी के अनुसार यह प्रतीत नहीं होता है जो आप चाहते हैं वही बनें। तो मैं सलाह देता हूं कि आप एमएसल्टर्स के रूप में करते हैं।

+0

'std :: endl' आउटपुट होने पर सामग्री को डंप करने के बाद, आपको शायद' oss' की सामग्री साफ़ करनी चाहिए ताकि अगली पंक्ति में आउटपुट दोहराया न जाए। –

+0

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

+0

@ डेविड - धन्यवाद, निश्चित @ धीरज - कोउट चीजें प्रिंट करते समय प्रिंट करता है (मुद्दों को अलग-अलग बफर करना)। – Manuel

4

प्रत्येक std::ostream के पीछे streambuf है। यह कैब को पुनर्प्राप्त किया जा सकता है और std::stream::rdbuf() के माध्यम से सेट किया जा सकता है। विशेष रूप से, इसे लपेटा जा सकता है - आप एक स्ट्रीमबफ ऑब्जेक्ट प्रदान कर सकते हैं जो स्ट्रीम किए गए टेक्स्ट को पोस्ट-प्रोसेस करता है। (postprocessing मतलब है कि आप std::cout << "123"; से std::cout << 123; भेद नहीं कर सकते)

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

1

प्रश्न यह चुनना है कि कब और कैसे सूचनाएं सिंक की जाएंगी - लाइन से? इसलिए कोई फर्क नहीं पड़ता कि यह बफर किया गया है या नहीं, ईओएल को नियंत्रित करने और लाइन पर सूचनाओं को नियंत्रित करने के अलावा कोई विकल्प नहीं है - इसे फ्लैश करना या प्रत्यक्ष आउटपुट।

यहां तक ​​कि अगर नाशक EOL/फ्लश के रूप में इस्तेमाल किया जा रहा है,

इनलाइन स्थानीय ढेर कोष्ठक वाक्य रचना आह्वान करने के लिए लॉग नाशक कोष्ठक बाहर निकलने, या std :: endl के रूप में के रूप में { log << [anything]; }, या तो इस्तेमाल किया जाना चाहिए।

जब तक इस तरह के रूप में कुछ संलग्न ऑपरेटर के साथ मेटा-वस्तु को लागू करने '< <' या "+ ', आप सभी तरह से एक स्पष्ट तरीका लाइन और या फ्लश

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