【问题标题】:c++ compiling error for reading object from file从文件读取对象的c ++编译错误
【发布时间】:2020-11-25 03:03:35
【问题描述】:

我将对象保存到文件中,在读回它们时,我想将其内容写入输出流。我确实为它添加了运算符重载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 &lt;&lt; c &lt;&lt; std::endl; 行中出现编译错误:

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

【问题讨论】:

  • 为什么需要与 FileWithClass 成为朋友?你不能把它写出来并模板化吗?
  • 如果我把它设为不是朋友,那么就会发生错误'std::ostream&amp; FileWithClass&lt;T&gt;::operator&lt;&lt;(std::ostream&amp;, T&amp;)' must have exactly one argument

标签: c++ file templates stream


【解决方案1】:

基本上,在您的类定义之外

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

您不需要添加friend 函数定义,因为您没有在operator&lt;&lt; 中使用任何私有成员。如果你是,你实际上需要在 MySpecificClass 中声明它的朋友,而不是你的模板,因为你的模板类无权访问 MySpecificClass 私有数据。

【讨论】:

  • 是的,你是对的。我确实将std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, MySpecificClass&amp; c) 移动到MySpecificClass 并且现在可以正常工作。谢谢。
猜你喜欢
  • 2017-03-21
  • 1970-01-01
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-11
相关资源
最近更新 更多