Как перегрузить std :: ofstream :: put ()? - PullRequest
3 голосов
/ 29 июня 2019

Я хочу записать значения 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 ]

1 голос
/ 29 июня 2019

Основные проблемы с вашим кодом (бесконечные рекурсивные вызовы) уже были правильно решены.

Использование явной области видимости, например

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

это исправит.

Я хочу записать значения int16_t в файл.

Хотя у меня сложилось впечатление, что вы хотите записать двоичные числа в сетевом байтовом порядке (с прямым порядком байтов) в файл, а не ставить символы в виде текста , и это не то, что вы наконец пытаетесь достигать.

Вот как я бы подошел к этому ( независимо от текущей архитектуры машины ):

#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).
Скорее используйте их как переменные-члены.

1 голос
/ 29 июня 2019

Ваша put() функция вызывает сама себя, а не версию базового класса. Таким образом, вы получаете бесконечную рекурсию, которая приводит к переполнению стека.

Заменить

put(lsb) && put(msb);

с

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