我正在使用 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;
}
没有汗水。然后我去申报>>
运算符(operator)。在.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&)’ must take exactly one argument
src/note.h:45: error: ‘void Note::operator>>(const YAML::Node&, Note&)’ must take exactly one argument
问题:我如何“正确地”重载 >>
一个类的运算符
- 不违反信息隐藏原则?
- 没有过度复制?
最佳答案
在不违反封装的情况下执行此操作的典型方法是使运算符>>成为友元函数。您对友元运算符的声明一定存在语法问题(不清楚错误消息中的确切内容)。我不使用 YAML,但从你的问题来看,以下是它的要旨:
class Note{
...
friend void operator >> ( const YAML::Node& node, Note& note );
....
};
void operator >> ( const YAML::Node& node, Note& note ){
node[0] >> note._number;
node[1] >> note._author;
node[2] >> note._subject;
node[3] >> note._body;
}
友元函数对私有(private)成员的访问权限与成员函数相同。
或者,您可以为所有成员数据声明 setter,但友元函数方法更简洁。
关于c++ - 在不违反信息隐藏的情况下重载流插入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2986974/