如何重载std :: ofstream :: put()?

时间:2019-06-29 08:46:42

标签: c++ ofstream

我想将int16_t值写入文件。

因此,我尝试重载std :: ofstream :: put()方法。

#include <fstream>
#include <cstdint>

class Ofstream : public std::ofstream
{
public:
    Ofstream( const std::string & s) : std::ofstream(s) {}

    // for little-endian machines
    Ofstream & put(int16_t val)
    {
        char lsb, msb;
        lsb = (char)val;
        val >>= 8;
        msb = (char)val;
        put(lsb) && put(msb);
        return *this;
    }
    ~Ofstream() {}
};
int main()
{
    int16_t val = 0x1234;
    Ofstream ofile( "test");
    ofile.put(val);
}

此时,我总是会遇到细分错误,那怎么了?

2 个答案:

答案 0 :(得分:1)

您的put()函数调用自身而不是基类版本。因此,您将获得无限递归,从而导致堆栈溢出。

替换

put(lsb) && put(msb);

使用

std::ofstream::put(lsb) && std::ofstream::put(msb);

答案 1 :(得分:1)

您的代码(无限递归调用)的主要问题已经得到正确解答。

使用类似的显式作用域

std::ofstream::put(lsb) && std::ofstream::put(msb);

将解决此问题。

  

我想将int16_t值写入文件。

尽管我给您的印象是您要以网络字节顺序(大端)将二进制数字写入文件,而不是put characters as text,但这并不是您最终要实现的目标。

这就是我要如何处理(independently of the current machine architecture):

#include <fstream>
#include <arpa/inet.h>

struct Ofstream {
    std::ofstream os;

    Ofstream( const std::string & s) : os(s,std::ios_base::binary) {}

    void put(uint16_t dt) {
        uint16_t netdt = htons(dt);
        os.write((char*)&netdt,sizeof(netdt))
    }
};

int main() {
    uint16_t val = 0x1234;
    Ofstream ofile("test");
    ofile.put(val);
}

通常,从标准库类继承不是一个好主意,除非明确地打算将它们用于实现(即std::ostream)。
而是将它们用作成员变量。