正确重载>> C ++中的运算符

时间:2016-11-10 10:13:05

标签: c++ operator-overloading

我找不到一个如何正确操作的正确例子。

以下代码写在FAQ中。

std::istream& operator>>(std::istream& is, T& obj)
{
  // read obj from stream

if( /* no valid object of T found in stream */ )
    is.setstate(std::ios::failbit);

return is;
}

如何检查“在流中找不到T的有效对象”?

1 个答案:

答案 0 :(得分:1)

您可以按照以下方式执行此操作:

通过以下方式将当前消息保存在输入流中:

streampos pos = is.tellg()

将数据从流读取到某个char缓冲区:

char tmp_buf[expected_size];
read(tmp_buf, expected_size);

// try to create a temporary object from read data
T tmp_obj = T::fromCharBuffer(tmp_buf) // you need to implement that

// If you get a valid object copy it to the destination
obj = tmp_obj

// in case of error revert previous stream position
if (error)
    is.seekg(pos)

return is

好的,忽略以上所有,我错了:

本主题可以更好地帮助您:

  

What's the right way to overload the stream operators << >> for my class?

更优雅的解决方案:

您必须插入/验证特定类的数据,因此您需要在某处实现此功能。您有3个选择:

  1. 特别是班级
  2. 在某个基类中
  3. 在您特定班级的朋友班(最佳选择)
  4. 我对方法3的实施

    class SomeClassParser:
    {
         // implement the functionality of creating SomeClass from stream.
         static SomeClass fromStream(ifstream &if)
         {
             // do your stream reading here and return SomeClass object
             // or throw parsing exception
         }
    
    };
    
    class SomeClass:
    {
        public:
            friend SomeClassParser;
            // points to the Parser class
            typedef SomeClassParser Parser;
            ...
    };
    
    template<typename T>
    ifstream& operator<<(ifstream &if, T& obj)
    {
        // do your type independent work, depending on your needs:
        // logging, stream recovery, error handling etc;
        // I'm not telling it's good or bad approach to recover the stream after failure
        // do what you need here
    
        // save stream
        streampos pos = is.tellg()
        try
        {
            obj = T::Parser::fromStream(if);
        }
        catch (int e):
        {
            // restore stream
            is.seekg(pos);
        }
    }
    

    使用此解决方案,您将不会破坏旧对象,以防分析错误发生。