Ошибка компиляции c ++ для чтения объекта из файла - PullRequest
1 голос
/ 05 августа 2020

Я сохранил объекты в файл и, читая их, хочу записать его содержимое в выходной поток. Я добавил для него перегрузку оператора friend std::ostream& operator<<(std::ostream& out, T& c), но как это сделать правильно?

#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);
}

В строке std::cout << c << std::endl; Я получаю ошибку компиляции:

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

1 Ответ

2 голосов
/ 05 августа 2020

В основном это вне определения вашего класса:

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

Вам не нужно добавлять определение функции friend, потому что вы не используете какие-либо частные члены в ваш operator<<. И если бы это было так, вам действительно нужно было бы объявить его другом в MySpecificClass, а не в вашем шаблоне, потому что ваш класс шаблона не имеет доступа к MySpecificClass частным данным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...