2012-01-06 4 views
0

Хорошо, я не могу получить этот код работы: Я хочу объединить мои пользовательские манипуляторы. , поэтому они будут называться как cout << endl. , например, я хочу это:Перегрузка операторов и манипуляторов письма?

emit << event1 << event2 << event3; 

вот мой код:

class Emit 
{ 
public: 
       // ... 
    const void operator<<(const Event& _event) const; 
}const emit; // note this global 

inline const void Emit::operator<<(const Event& _event) const 
{ 
    Start(_event); 
} 


class Event 
{ 
       // ... 
     const Event& Event::operator<<(const Event& _event) const; 
}; 

inline const Event& Event::operator<<(const Event& _event) const 
{ 
    return _event; 
} 

Однако я не могу назвать это:

emit << event1 << event2 << event3; 

Я Eather получения компиляции ошибки времени, время ссылки ошибки и то, что когда-либо я меняю в своем коде, я получаю несоответствующую ошибку, но не успех.

, например, вот этот:

Ошибка 1 ошибка C2679: бинарный '< <': ни один оператор не найден, который принимает правый операнд типа 'Const EventHandling :: Event' (или есть не приемлемо преобразование) C: \ Users \ Admin \ документы не \ Visual Studio 2010 \ проекты \ cppsystem \ eventhandling \ test.h 18

Большое спасибо.

ответ

2

Эти операторы вызываются слева направо. Таким образом, первый вызов (emit << event1) должен возвращать ссылку на Emit:

class Emit 
{ 
public: 
    // ... 
    Emit const& operator<<(const Event& _event) const; 
}const emit; // note this global 

Emit const& Emit::operator<<(const Event& _event) const 
{ 
    Start(_event); 
    return *this; 
} 

И теперь вам не нужно перегружать operator<< в вашем Event классе больше.

+0

ahahah: D Я получаю это сейчас, благодаря большому Xeo, вы просто сохранили жизнь моей клавиатуры! ваш код работает как шарм. – codekiddy

1

Если ваши манипуляторы не содержат никаких данных, вы можете просто написать функцию. Например, std::endl реализуется примерно так (это необходимо, чтобы справиться с большими потоками, а также и тем самым делает некоторые магии, чтобы организовать символы быть преобразованы):

std::ostream& endl(std::ostream& out) { 
    (out << '\n').flush(); 
    return out; 
} 

Если манипуляторы имеют некоторые данные, которые нужно хранить данные в подходящем объекте, а затем просто создать нормальный выходной оператор для этого класса, например std::setw() могут быть реализованы, как это (опять же, не обращая внимания, что потоки фактически шаблоны):

struct std::setw { 
    setw(int size): size_(size) {} 
    int size_; 
}; 
std::ostream& operator<< (std::ostream& out, std::setw const& object) { 
    out.width(object.size_); 
    return out; 
} 

Вы можете реализовать выход операторов в член, потому что вы не контролируете левую сторону operator<<(): здесь находится объект потока. Если вы использовали std::ostream, вы могли бы реализовать эти элементы (ну, на самом деле, стандартные мандаты, что некоторые операторы вывода являются членами std::ostream).

+0

О, спасибо за эту ценную информацию, проголосуйте +, но я уже принял ответ от Xeo, так как он отправил в миниатюре. еще раз спасибо!! – codekiddy