Я хочу создать класс регистратора, таким образом что с функциональностью как это:
Logger log;
log << "Error: " << value << "seen" << endl;
Это должно распечатать меня пользовательское форматированное сообщение. Например, "09.12.2009 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";
}
Это заставит oss правильно иметь буферную "Ошибку: 5 замеченных". Но я не знаю то, что другую функцию я должен писать/изменять так, чтобы что-то распечатало на экране. Кто-либо знает, как заставить это работать или является там другим способом разработать этот класс, чтобы иметь мою работу функциональности?
Насколько я понимаю, ваш регистратор ничем не отличается от ostringstream. Он просто берет то, что дано, и выводит это в поток строк. Если вы хотите использовать его таким образом, вы можете написать деструктор для Logger, который выводит строку в cout.
Logger::~Logger()
{
std::cout<<getcurrentDateTimeAsString()<<" "<<oss.str()<<std::endl;
}
Но, конечно, это не имеет смысла, если Logger * создается и используется во всей программе.
За каждым std :: ostream
стоит streambuf
. Его можно получить и установить с помощью std :: stream :: rdbuf ()
. В частности, его можно обернуть - вы можете предоставить объект streambuf, который пост-обрабатывает передаваемый текст.
( постобработка означает, что вы не можете отличить std :: cout << 123;
от std :: cout << "123";
)
В вашем конкретном случае постобработка довольно проста. В начале каждой строки вы хотите вставить несколько байтов. Это просто означает, что вы должны следить за тем, выводили ли вы уже префикс для текущей строки. Если нет, сделайте это и установите флаг. И всякий раз, когда вы видите новую строку, сбросьте ее. В вашей оболочке streambuf есть только одно состояние типа bool
.
Это (из этого поста) делает то, что вы хотите, но это заставляет вас заканчивать каждую строку 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();
}
EDIT: Ну, в соответствии с вашим комментарием, это не то, что вы хотите. Тогда я рекомендую вам делать то, что говорит MSalters.