2015-03-28 6 views
1

Почему у меня все еще есть ОШИБКА: exepected идентификатор в std::ofstream << val на строке ниже? MSVC.Переопределение операционного оператора <<

std::ostream& operator<< (bool val) { m_lock.lock(); std::ofstream << val; m_lock.unlock(); return *this; } 
class OfstreamLog : public std::ofstream { 

    private: 

     std::mutex m_lock; 

    public: 

     OfstreamLog() : std::ofstream() { } 
     explicit OfstreamLog(const char* filename, ios_base::openmode mode = ios_base::out) : std::ofstream(filename, mode) { } 

     std::ostream& operator<< (bool val) { m_lock.lock(); std::ofstream << val; m_lock.unlock(); return *this; } 
     std::ostream& operator<< (short val); 
     std::ostream& operator<< (unsigned short val); 
     std::ostream& operator<< (int val); 
     std::ostream& operator<< (unsigned int val); 
     std::ostream& operator<< (long val); 
     std::ostream& operator<< (unsigned long val); 
     std::ostream& operator<< (float val); 
     std::ostream& operator<< (double val); 
     std::ostream& operator<< (long double val); 
     std::ostream& operator<< (void* val); 
     std::ostream& operator<< (std::streambuf* sb); 
     std::ostream& operator<< (std::ostream& (*pf)(std::ostream&)); 
     std::ostream& operator<< (std::ios& (*pf)(std::ios&)); 
     std::ostream& operator<< (ios_base& (*pf)(ios_base&)); 

    }; 
+0

Зачем вам нужно переопределять '<<'? –

+0

@ Golazo: посмотрите код, мне нужно синхронизировать запись через оператор << – Krab

+1

Не по теме, но подумайте об использовании 'std :: lock_guard'. – chris

ответ

6

std::ofstream это имя типа. Вы не можете вызвать для него нестатический метод или оператор без какого-либо объекта.

В этом случае вы, вероятно, захотите std::ofstream::operator<<(val); вместо std::ofstream << val;.


Объяснение:

Если вы хотите вызвать метод родительского класса из метода класса ребенка, вы делаете это так:

class A 
{ 
    void func() {} 
}; 

class B 
{ 
    void test() 
    { 
     func(); // Like this 
    } 
}; 

Но если ребенок класса есть метод с тем же именем (точнее, с той же подписи (это означает, что имя и тип аргумента)), он будет вызываться вместо родительского. Для явного вызова метода родительского класса, вы можете использовать этот синтаксис:

class A {...}; 
class B 
{ 
    void test() 
    { 
     A::func(); // Notice `A::` 
    } 
}; 



Теперь давайте поговорим об операторах. Когда вы хотите вызвать оператора, вы обычно используете для него имя объекта, например object << 10;. Но если вы хотите, чтобы позвонить оператору класса (или его родители) из метода этого класса, вы должны использовать полный operator синтаксис:

class A 
{ 
    operator<<(int){} 
}; 
class B 
{ 
    void test() 
    { 
     operator<<(10); // <----- 
     *this << 10; // Also you can do it like this 
    } 
}; 



Теперь мы объединим эти два метода:
Если у child class есть оператор с той же подписью, что и родительский, и вы хотите вызвать оператора родителя, вы делаете это так:

class A {...}; 
class B 
{ 
    void test() 
    { 
     A::operator<<(10); // Notice `A::` 
     *(A*)this << 10; // Also you can do it like this 
    } 
}; 
Смежные вопросы