2014-05-01 3 views
1

я пытаюсь написать класс протоколирования, где вы будете в состоянии сделать что-то вроде этогоC++ прохождение потока в методе класса

//Create an instance of a class 
Log log; 

log.debug() << "a string " << 42 << endl; 
log.info() << "another string " << 41 << endl; 

Это произведет следующий вывод на стандартный вывод

Info: a string 42 
Debug: another string 41 

Вот что я был в состоянии достигнуть до сих пор

#include <iostream> 
#include <string> 
#include <sstream> 

#define endl '\n' 

using std::cout; 
using std::string; 
using std::stringstream; 

class Log { 
    public: 
     Log() {} 
     ~Log() {} 

     //Create buffer to store everything 
     stringstream buffer; 

     //Create templase class to overload << 
     template <class T> 
     inline Log & operator << (T data) { 
       buffer << data; 
       return *this; 
     } 

     inline Log & debug() { 
       print("Debug: "); 
     } 

     inline Log & info() { 
       print("Info: "); 
     } 

     inline void print(string type) { 
       //Display the contents of the buffer to standard output 
       cout << type << buffer.str(); 
       //Clear the buffer 
       buffer.str(string()); 
     } 
}; 

int main() { 
     Log log; 
     log << "Hello " << "World " << 5 << " " << 2.3 << endl; 
     log.debug(); 

     log << "Hello Again " << 42 << endl; 
     log.info(); 
     return 0; 
} 

Это дает правильный вывод, но этот путь EAC h строка регистрации занимает две строки кода и очень громоздка. Может ли кто-нибудь уйти с пути, я могу сделать log.debug() < < «материал»? Это очень простой пример, в более поздних версиях вместо простой строки будут отметки времени, даты, имена пользователей и т. Д., Поэтому я пытаюсь получить каждый уровень журнала, обрабатываемый другой функцией.

Я предполагаю, что мне понадобится другой оператор перегрузки оператора, но я просто не могу понять, что это должно быть. Также текущий оператор шаблона < < не любит std :: endl (не компилируется, если я его использую), поэтому я просто устанавливаю endl = '\ n' вверху.

Заранее благодарим вас за перспективу обучения в максимально возможной степени.

+3

Поиск в StackOverflow и в Интернете для «класса ведения журнала C++». Это было сделано раньше. –

+1

have 'Log :: debug()' возвращает тип, который поддерживает оператор '<<'. Вы не совсем поняли, что вы пытаетесь сделать - если вы хотите, чтобы 'log.debug() <<" stuff "' обрабатывал '' stuff ''как параметр вашей функции' debug() ', тогда no , вы не можете этого сделать. Просто используйте параметры. –

+0

Попробуйте вернуть ссылку ostream из 'debug()' и оттуда оттуда. – OMGtechy

ответ

0

Это звучит как то, что вы хотите, чтобы ваши debug и info функции возвращать что-то вроде std::stringstream, который будет поддерживать operator<<, но как-то и промывать выход после этого. Если это так, вам лучше использовать что-то вроде функции variadic template.

Что касается вашей другой проблемы, то std::endl на самом деле является шаблоном, поэтому его тип не может использоваться как T для Log::operator<< <T> (T). Это один из примеров того, почему не стоит пытаться переопределить функциональность потока. Перегрузка, которая позволяет вам писать << std::endl, объявляется примерно как template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits> & operator<<(basic_ostream<_CharT, _Traits>&, basic_ostream<_CharT, _Traits> &(basic_ostream<_CharT, _Traits> &)). std::endl - это шаблон функции, который принимает ostream, добавляет новую строку и очищает поток.

Следует также отметить, что ваши функции debug и info не возвращают значение. Если вы используете GCC, предупреждение для этого отключено по умолчанию, но это может быть очень сложным источником неопределенного поведения. Используйте -Wreturn-type, чтобы включить его, когда вы создадите что-то важное.

Смежные вопросы