Pasha
Pasha

Reputation: 89

c++ compiling error for reading object from file

I saved objects to file and while reading them back i want to write it content to output stream. I did add operator overloading for it friend std::ostream& operator<<(std::ostream& out, T& c) but how to do it in correct way?

#include <iostream>
#include <fstream>

class MySpecificClass {
    std::string data;
    unsigned int x;
    unsigned int y;
    unsigned int z;

public:
    MySpecificClass(): data(""), x(0), y(0), z(0) {}

    MySpecificClass(std::string s, unsigned int xx, unsigned int yy, unsigned zz) : data(s), x(xx), y(yy), z(zz) {}

    std::string Print() {
        std::string s = "data: " + data + "\tx=" +  std::to_string(x) + ",\ty=" +  std::to_string(y) + ",\tz=" +  std::to_string(z);
        return s;
    }
};


template <class T>
class IFileClass {
public:
    IFileClass(std::string f) : fileName(f) {}
    virtual void save(T& c) = 0;
    virtual void read(T& c) = 0;

protected:
    std::string fileName;
    std::ofstream fout;
    std::ifstream fin;
};

template <class T>
class FileWithClass : public IFileClass<T> {
public:
    FileWithClass(std::string fn) : IFileClass<T>(fn) {
        std::cout << "FileWithClass constructor" << std::endl;
    }

    friend std::ostream& operator<<(std::ostream& out, T& c) {
        out << c.Print();
        return out;
    }

    void save(T& c) override {
        if (this->fileName == "")
            throw new std::runtime_error("path is empty");

        this->fout.open(this->fileName, std::ofstream::app);
        if (this->fout.is_open()) {
            this->fout.write((char*)&c, sizeof(T));
            this->fout.close();
            std::cout << "saved" << std::endl;
        } else {
            std::cout << "File open error" << std::endl;
        }
    }

    void read(T& c) override {
        if (this->fileName == "")
            throw new std::runtime_error("path is empty");

        this->fin.open(this->fileName);
        if (this->fin.is_open()) {
            while (this->fin.read((char*)&c, sizeof(T))) {
                std::cout << c << std::endl;
            }
            this->fin.close();
        } else {
            std::cout << "File open error" << std::endl;
        }
    }
};

int main() {
    MySpecificClass msc = {"My text", 1, 2, 3};

    FileWithClass<MySpecificClass> fsv = {"test.txt"};
    fsv.save(msc);
    fsv.read(msc);
}

In line std::cout << c << std::endl; I get a compile error:

main.cpp|71|error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'MySpecificClass')

Upvotes: 1

Views: 94

Answers (1)

Adrien Leravat
Adrien Leravat

Reputation: 2789

Basically this, outside of your class definition:

std::ostream& operator<<(std::ostream& out, MySpecificClass& c) {
    out << c.Print();
    return out;
}

You don't need to add the friend function definition, because you are not using any private members in your operator<<. And if you were, you would actually need to declare it friend in MySpecificClass, and not your template, because your template class has no access to MySpecificClass private data.

Upvotes: 2

Related Questions