Я использую yaml-cpp для проекта. Я хочу перегрузить операторы <<
и >>
для некоторых классов, но у меня возникла проблема с тем, как это сделать "правильно". Возьмем, к примеру, класс Note
. Это довольно скучно:
class Note {
public:
// constructors
Note( void );
~Note( void );
// public accessor methods
void number( const unsigned long& number ) { _number = number; }
unsigned long number( void ) const { return _number; }
void author( const unsigned long& author ) { _author = author; }
unsigned long author( void ) const { return _author; }
void subject( const std::string& subject ) { _subject = subject; }
std::string subject( void ) const { return _subject; }
void body( const std::string& body ) { _body = body; }
std::string body( void ) const { return _body; }
private:
unsigned long _number;
unsigned long _author;
std::string _subject;
std::string _body;
};
Оператор <<
— это легкий соус. В .h
:
YAML::Emitter& operator << ( YAML::Emitter& out, const Note& v );
И в .cpp
:
YAML::Emitter& operator << ( YAML::Emitter& out, const Note& v ) {
out << v.number() << v.author() << v.subject() << v.body();
return out;
}
Нет пота. Затем я объявляю оператор >>
. В .h
:
void operator >> ( const YAML::Node& node, Note& note );
Но в .cpp
я получаю:
void operator >> ( const YAML::Node& node, Note& note ) {
node[0] >> ?
node[1] >> ?
node[2] >> ?
node[3] >> ?
return;
}
Если я напишу что-то вроде node[0] >> v._number;
, то мне нужно будет изменить квалификатор CV, чтобы сделать все поля Note
public
(что опровергает все, чему меня учили (профессора, книги и опыт)) о сокрытии данных.
Я чувствую, что делать node[0] >> temp0; v.number( temp0 );
повсюду не только утомительно, подвержено ошибкам и уродливо, но и довольно расточительно (что с дополнительными копиями).
Потом я сообразил: я попытался переместить эти два оператора в сам класс Note
и объявить их как friend
s, но компилятору (GCC 4.4) это не понравилось:
src/note.h:44: error: 'YAML::Emitter& Note::operator‹‹(YAML::Emitter&, const Note&)' должен принимать ровно один аргумент
src/note.h:45: error: ' void Note::operator>>(const YAML::Node&, Note&)' должен принимать ровно один аргумент
Вопрос: как "правильно" перегрузить оператор >>
для класса
- Не нарушая принцип сокрытия информации?
- Без лишнего копирования?
operator<<
в качестве функции-члена говорят вам, что когда вы переопределяете оператор как функцию-член, левый операнд должен относиться к этому типу класса, а правая часть является единственным аргументом. оператора. Вы не можете переопределить оператор, который принимаетYAML::Emitter
в качестве первого аргумента в качестве члена класса вне классаYAML::Emitter
. - person David Rodríguez - dribeas   schedule 07.06.2010const
ссылке. - person sbi   schedule 07.06.2010