在从字符串流读取和写入自定义对象时测试失败

Tests failing, when reading and writing a custom object from and to a stringstream

没有语法错误,这不是 Pixel_test.cpp 和 Pixel.cpp 的完整代码。

我只有完整的头文件。

失败的测试是 assert(actual == correct);

我在想,问题出在 std::ostream&std::istream& 中的 Pixel.cpp 文件。

我花了几个小时,试图找出为什么这个测试不起作用,所以我来这里寻求帮助。

Pixel_test.cpp:

   stringstream in, out;
   string correct;
   Pixel pix;
   pix.set(5,3,2);
   correct = 5,3,2;
   out << pix;
   string actual = out.str();
   assert(actual == correct);
   in << (6,4,6);
   in >> pix;
   assert(pix.getRed() == 6);
   assert(pix.getBlue() == 6);
   assert(pix.getGreen() == 4);

Pixel.cpp:

std::ostream& operator<<(std::ostream& out, const Pixel& pix)
{
     int r, g, b;
     r = pix.getRed();
     g = pix.getGreen();
     b = pix.getBlue();
     out << r << g << b;
     return(out);
}
std::istream& operator>>(std::istream& out, Pixel& pix)
{
     int r, g, b;
     pix.setRed(r);
     pix.setGreen(g);
     pix.setBlue(b);
     out >> r >> g >> b;
     return out;
}

Pixel.h:

#ifndef PIXEL_H
#define PIXEL_H

namespace imagelab
{
    class Pixel
    {
     public:
        Pixel( int r=0, int g=0, int b=0 );     
        void set( int r, int g, int b );
        void setRed( int r );
        void setGreen( int g );
        void setBlue( int b );
        int getRed( ) const;
        int getGreen( ) const;
        int getBlue( ) const;

     private:
        int rval;   // red 0-255
        int gval;   // green 0-255
        int bval;   // blue 0-255
    };

    bool operator== (const Pixel& pix1, const Pixel& pix2);
    bool operator!= (const Pixel& pix1, const Pixel& pix2);
    std::ostream& operator<< (std::ostream& out, const Pixel& pix);
    std::istream& operator>> (std::istream& in, Pixel& pix);
}

#endif

要使 assert(actual == correct); 正常工作,两个 string 应该完全相同,但您的情况并非如此。

所以,替换:

correct = 5,3,2;

Pixel_test.cpp 中:

correct = "5,3,2";

并替换:

out << r << g << b;

std::ostream& operator<<(std::ostream& out, Pixel& pix) 中:

out << r << ',' << g << ',' << b;

out << pix; 呈现相同的输出。

通过进行上述更改,您的 assert(actual == correct); 将停止失败。

但是,之后的 assertss 可能会失败,因为当您调用 in>>pix; 时,会调用此函数:

std::istream& operator>>(std::istream& out, Pixel& pix)
{
 int r, g, b;
 pix.setRed(r);
 pix.setGreen(g);
 pix.setBlue(b);
 out >> r >> g >> b;
 return out;
}

而且我们可以清楚地看到 r gb 在调用它们各自的 set 方法之前没有被赋值。

因此,只有 垃圾值 存储在 rval bvalgvalpix

这就是为什么 asserts:

assert(pix.getRed() == 6);
assert(pix.getBlue() == 6);
assert(pix.getGreen() == 4);

注定要失败。

编辑:

要更正此问题,您需要将刚刚放入流中的输入读入变量 r gb.

所以,像这样更改 std::istream& operator>>(std::istream& out, Pixel& pix) 函数:

std::istream& operator>>(std::istream& out, Pixel& pix)
{
 int r, g, b;
 out >> r >> g >> b;
 pix.setRed(r);
 pix.setGreen(g);
 pix.setBlue(b);
 return out;
}

同时替换:

in << (6,4,6);

在您的 Pixel_test.cpp 文件中:

in << "6 4 6";

因为 stringstream 将数据存储为 string