ofstream и перегрузка <<
От: cs_student  
Дата: 07.04.07 15:37
Оценка:
Имеется следующий класс.


class Log: public ofstream
{
public:
    Log(char* szLogFn=LOG_FILE);
    ~Log();
    ofstream& operator<<(const char* szmsg);
    ofstream& operator<<(int ival);
    ofstream& operator<<(double dval);
private:
        // ...
};

Log::Log(char* szLogFn): ofstream(szLogFn,ios_base::out)
{
    this->szLogFn=new char[strlen(szLogFn)+1];
    strcpy_s(this->szLogFn,strlen(szLogFn)+1,szLogFn);
    InitializeCriticalSection(&csLog);
}

Log::~Log()
{
    close();
    delete[] szLogFn;
    DeleteCriticalSection(&csLog);
}

ofstream& Log::operator<<(const char* szmsg)
{
    EnterCriticalSection(&csLog); 
    ofstream::operator<<(szmsg); 
    flush(); 
    LeaveCriticalSection(&csLog);
    return *this;
}
ofstream& Log::operator<<(int ival)
{
    EnterCriticalSection(&csLog); 
    ofstream::operator<<(ival); 
    flush(); 
    LeaveCriticalSection(&csLog);
    return *this;
}
ofstream& Log::operator<<(double dval)
{
    EnterCriticalSection(&csLog); 
    ofstream::operator<<(dval); 
    flush(); 
    LeaveCriticalSection(&csLog);
    return *this;
}

Если в Log записывать числа, всё работает как надо, а для строк записывается опять число, и такое впечатление, что это адрес szmsg. Почему так происходит?
Re: ofstream и перегрузка <<
От: Chorkov Россия  
Дата: 07.04.07 16:36
Оценка:
Здравствуйте, cs_student, Вы писали:

_>Имеется следующий класс.



_>
_>class Log: public ofstream
_>{
_>public:
_>    Log(char* szLogFn=LOG_FILE);
_>    ~Log();
_>    ofstream& operator<<(const char* szmsg);
_>    ofstream& operator<<(int ival);
_>    ofstream& operator<<(double dval);
_>private:
_>        // ...
_>};

_>


...

_>Если в Log записывать числа, всё работает как надо, а для строк записывается опять число, и такое впечатление, что это адрес szmsg. Почему так происходит?


Потому что operator<< в std::ostream определен только для const void *, но не для const char *.
для вывода стандарнтных строк используется оператор определенный не в теле класса:



template<class _Traits> inline
    basic_ostream<char, _Traits>& __CLRCALL_OR_CDECL operator<<(
        basic_ostream<char, _Traits>& _Ostr,
        const char *_Val)



Рискну посоветовать использовать:

class Log: public ofstream
{
public:
    Log(char* szLogFn);
    ~Log();

    template<class C>
    Log& operator<<(const C& c)
    {
        EnterCriticalSection(&csLog); 
        static_cast<ofstream&>(*this) << c;
        flush(); 
        LeaveCriticalSection(&csLog);
        return *this;

    }

private:
};
Re[2]: ofstream и перегрузка <<
От: cs_student  
Дата: 07.04.07 16:58
Оценка:
Здравствуйте, Chorkov, Вы писали:


C>Рискну посоветовать использовать:


C>
C>class Log: public ofstream
C>{
C>public:
C>    Log(char* szLogFn);
C>    ~Log();

C>    template<class C>
C>    Log& operator<<(const C& c)
C>    {
C>        EnterCriticalSection(&csLog); 
C>        static_cast<ofstream&>(*this) << c;
C>        flush(); 
C>        LeaveCriticalSection(&csLog);
C>        return *this;

C>    }

C>private:
C>};
C>


Тогда компилятор говорит "error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion)".
Re[3]: ofstream и перегрузка <<
От: Chorkov Россия  
Дата: 07.04.07 17:10
Оценка:
Здравствуйте, cs_student, Вы писали:

_>Здравствуйте, Chorkov, Вы писали:



C>>Рискну посоветовать использовать:


C>>
C>>class Log: public ofstream
C>>{
C>>public:
C>>    Log(char* szLogFn);
C>>    ~Log();

C>>    template<class C>
C>>    Log& operator<<(const C& c)
C>>    {
C>>        EnterCriticalSection(&csLog); 
C>>        static_cast<ofstream&>(*this) << c;
C>>        flush(); 
C>>        LeaveCriticalSection(&csLog);
C>>        return *this;

C>>    }

C>>private:
C>>};
C>>


_>Тогда компилятор говорит "error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion)".




Проверял на VS2005 следующем примере:
#include <iostream>
#include <fstream>
using namespace std;

class Log: private ofstream
{
public:
    Log(char* szLogFn);
    ~Log();

    template<class C>
    Log& operator<<(const C& c)
    {
        static_cast<ofstream&>(*this) << c;
        return *this;
    }
private:
};


Log::Log(char* szLogFn): ofstream(szLogFn,ios_base::out)
{}

Log::~Log()
{}

int main()
{
    Log a("c:\\log");
    a<<"1";
    a<<" "<<2;
    a<<"\t"<<1.1<< " ";
}

Все работало

1) какой компилятор?
2) используем ли ты fastream из <fstream> или устаревший из <fstream.h> ?
3) на аргументе какого типа выдается это сообщение об ошибке ?
Re[4]: ofstream и перегрузка <<
От: cs_student  
Дата: 07.04.07 17:21
Оценка:
C>1) какой компилятор?
C>2) используем ли ты fastream из <fstream> или устаревший из <fstream.h> ?
C>3) на аргументе какого типа выдается это сообщение об ошибке ?

1) Visual C++ 2005 express edition
2) <fstream>
3) endl
Re[5]: ofstream и перегрузка <<
От: Chorkov Россия  
Дата: 07.04.07 18:30
Оценка:
Здравствуйте, cs_student, Вы писали:

C>>1) какой компилятор?

C>>2) используем ли ты fastream из <fstream> или устаревший из <fstream.h> ?
C>>3) на аргументе какого типа выдается это сообщение об ошибке ?

_>1) Visual C++ 2005 express edition

_>2) <fstream>
_>3) endl



Для манипуляторов потребуется написать отдельную специализацию:

class Log  : public ofstream
{
public:
    Log(char* szLogFn);
    ~Log();

    template<class C>
    Log& operator<<(const C& c)
    {
        static_cast<ofstream&>(*this) << c;
        return *this;
    }

    Log& operator<<(ostream& (*manipulator)(ostream&))
    {
        static_cast<ostream&>(*this)<<manipulator;
        return *this;
    };
private:
};


Проверил со стандартными манипуляторами работает.
Возможно, потребуется написать еще специализации для ios_base& (*m)(ios_base&) и для basic_ios<>& (*m)(basic_ios<>&)
Re[6]: ofstream и перегрузка <<
От: cs_student  
Дата: 07.04.07 21:25
Оценка:
Теперь всё работает. Спасибо.
Re: ofstream и перегрузка <<
От: LuciferMoscow Россия  
Дата: 08.04.07 09:29
Оценка: +1
Здравствуйте, cs_student, Вы писали:

Может так
_>[ccode]
_>class Log//: public ofstream
_>{
ofstream stream_;
_>public:
_> Log(char* szLogFn=LOG_FILE);
_> ~Log();
_> ofstream& operator<<(const char* szmsg);
_> ofstream& operator<<(int ival);
_> ofstream& operator<<(double dval);
_>private:
_> // ...
_>};

лучше?
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.