Overloading stream insertion without violating information hiding?
Posted
by Chris
on Stack Overflow
See other posts from Stack Overflow
or by Chris
Published on 2010-06-07T03:46:32Z
Indexed on
2010/06/07
3:52 UTC
Read the original article
Hit count: 252
I'm using yaml-cpp for a project. I want to overload the <<
and >>
operators for some classes, but I'm having an issue grappling with how to "properly" do this. Take the Note
class, for example. It's fairly boring:
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;
};
The <<
operator is easy sauce. In the .h
:
YAML::Emitter& operator << ( YAML::Emitter& out, const Note& v );
And in the .cpp
:
YAML::Emitter& operator << ( YAML::Emitter& out, const Note& v ) {
out << v.number() << v.author() << v.subject() << v.body();
return out;
}
No sweat. Then I go to declare the >>
operator. In the .h
:
void operator >> ( const YAML::Node& node, Note& note );
But in the .cpp
I get:
void operator >> ( const YAML::Node& node, Note& note ) {
node[0] >> ?
node[1] >> ?
node[2] >> ?
node[3] >> ?
return;
}
If I write things like node[0] >> v._number;
then I would need to change the CV-qualifier to make all of the Note
fields public
(which defeats everything I was taught (by professors, books, and experience))) about data hiding.
I feel like doing node[0] >> temp0; v.number( temp0 );
all over the place is not only tedious, error-prone, and ugly, but rather wasteful (what with the extra copies).
Then I got wise: I attempted to move these two operators into the Note
class itself, and declare them as friend
s, but the compiler (GCC 4.4) didn't like that:
src/note.h:44: error: ‘YAML::Emitter& Note::operator<<(YAML::Emitter&, const Note&)’ must take exactly one argument
src/note.h:45: error: ‘void Note::operator>>(const YAML::Node&, Note&)’ must take exactly one argument
Question: How do I "properly" overload the >>
operator for a class
- Without violating the information hiding principle?
- Without excessive copying?
© Stack Overflow or respective owner