c++ - 在不违反信息隐藏的情况下重载流插入?

标签 c++ operator-overloading information-hiding yaml-cpp

我正在使用 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

问题:我如何“正确地”重载 >>一个类的运算符

  1. 不违反信息隐藏原则?
  2. 没有过度复制?

最佳答案

在不违反封装的情况下执行此操作的典型方法是使运算符>>成为友元函数。您对友元运算符的声明一定存在语法问题(不清楚错误消息中的确切内容)。我不使用 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/

相关文章:

c++ - 友元函数声明为成员函数

c++ - 为类/信息隐藏创建内部和外部接口(interface)

language-agnostic - 将 *interface* 或 *object* 作为参数传递给函数会更好吗?

c++ - 封装一个 "include"所以只暴露选定的类

c++ - 用 BFS 找路

c++ - 为什么迭代器没有到达 vector 的末尾?

c++ - 将 OpenGL VBO 与自定义类/数据结构一起使用

c++ - 模板特化 : Const& versus Const*

c++ - vector 运算符和类型转换

c++ - 对类实例和 vector 使用赋值运算符