2011-12-09 39 views
8

मुझे एक सी ++ कक्षा मिली है जिसे मैं लॉगिंग के लिए उपयोग की जाने वाली स्ट्रीम पकड़ना चाहता हूं।सी ++ स्ट्रीम सदस्य चर के रूप में

स्ट्रीम ऑब्जेक्ट के निर्माण के बाद सेट (और संभवतः रीसेट) करने में सक्षम होना चाहिए।

यह std::cout के रूप में धारा निर्धारित करना संभव हो सकता है, या एक फ़ाइल धारा के रूप में एक फ़ाइल में लॉग इन करने के लिए, या एक stringstream से अधिक डेटा (एक तरह के /dev/null) की उपेक्षा कुछ नहीं करता है के रूप में। किसी भी मामले में, यह ostream प्रकार ऑब्जेक्ट होना चाहिए, जो ऑब्जेक्ट का निर्माता किसी भी समय रीसेट कर सकता है। वर्ग स्वयं कंक्रीट स्ट्रीम प्रकार से अनजान है।

मैं एक ostream के सूचक के साथ यह पूरा कर सकता है, लेकिन फिर एक छोटे से वाक्य रचना कष्टप्रद हो जाता है, deref ऑपरेटर का उपयोग किए:

(*m_log) << "message"; 

बजाय

m_log << "message"; 

लेकिन मैं कर सकते हैं संदर्भों का उपयोग नहीं करते हैं, क्योंकि ऑब्जेक्ट प्रारंभ होने के बाद स्ट्रीम ऑब्जेक्ट को संभवतः रीसेट करने की आवश्यकता होती है।

क्या यह हासिल करने का एक शानदार तरीका है, यानी, पॉइंटर्स का उपयोग करने से बचें, लेकिन फिर भी निर्माण के बाद रीसेट करने में सक्षम हो?

+2

पर रहते हैं क्यों आप अपने सिस्टम के लिए एक संदर्भ लौटने एक छोटा सा सदस्य समारोह प्रदान नहीं करते देखा है? रास्ते के साथ कुछ: ostream और mlog() {वापसी * ​​m_log;}। फिर आप लिखेंगे: mlog() << "message"; – fjardon

+0

एक पॉइंटर का उपयोग करें, और अपने कार्य को 'std :: ostream & o = * m_log; 'के साथ शुरू करें। –

+2

@fjardon: आप इसे एक छोटे से उत्तर के रूप में क्यों नहीं प्रदान करते? ; पी – Xeo

उत्तर

9

आपको स्ट्रीम रीसेट कर सकते हैं: यह https://ideone.com/Ci4eo

#include <fstream> 
#include <iostream> 
#include <string> 

struct Logger 
{ 
    Logger(std::ostream& os) : m_log(os.rdbuf()) { } 

    std::streambuf* reset(std::ostream& os) 
    { 
     return m_log.rdbuf(os.rdbuf()); 
    } 

    template <typename T> friend Logger& operator<<(Logger& os, const T& t) 
    { os.m_log << t; return os; } 

    friend Logger& operator<<(Logger& os, std::ostream& (*pf)(std::ostream&)) 
    { os.m_log << pf; return os; } 

    private: 
    std::ostream m_log; 
}; 

int main(int argc, const char *argv[]) 
{ 
    Logger logto(std::cout); 

    logto << "Hello world" << std::endl; 

    logto.reset(std::cerr); 
    logto << "Error world" << std::endl; 

    return 0; 
} 
+0

यह एक अच्छा समाधान है, ठीक उसी तरह के साथ जो मैं देख रहा था के लिये। इसे विस्तारित किया जा सकता है (वैकल्पिक रूप से) एक दूसरी धारा जोड़ें, उदाहरण के लिए, टी बनाना। मैं इसे ऊपर उठाऊंगा ... अगर मेरे पास पर्याप्त प्रतिष्ठा थी। (: धन्यवाद। –

+0

यदि आप टी-स्ट्रीम जैसे सुविधाओं की तलाश में हैं, तो [बूस्ट Iostreams] (http://www.boost.org/doc/libs/1_48_0/libs/iostreams/doc/index पर एक नज़र डालें। एचटीएमएल? पथ = 1), उदाहरण के लिए [टीई फ़िल्टर] (http://www.boost.org/doc/libs/1_48_0/libs/iostreams/doc/functions/tee.html#tee_filter) [पाइपलाइन] के साथ संयोजन में (http://www.boost.org/doc/libs/1_48_0/libs/iostreams/doc/guide/pipelines.html) – sehe

4

खुद को परेशान क्यों करें?

class foo{ 
public: 
    // .. 
private: 
    std::ostream& log() const{ return *m_log; } 
    mutable std::ostream* m_log; 
}; 

और इसके बजाय log() << "blah\n"; का उपयोग करें।

+1

आपका मतलब है कि समारोह में 'वापसी * ​​m_log;' है। –

+1

@ जेम्स: मुझे नहीं पता कि आपका क्या मतलब है। ♪ – Xeo

+0

पृष्ठ को रीफ्रेश करने से पहले लॉग विधि में कोई * नहीं था। –

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