首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从文件中读取对象的c++编译错误

从文件中读取对象的c++编译错误
EN

Stack Overflow用户
提问于 2020-08-05 00:09:52
回答 1查看 67关注 0票数 1

我将对象保存到文件中,在读取对象时,我希望将其内容写入输出流。我确实为它添加了操作符重载,friend std::ostream& operator<<(std::ostream& out, T& c),但是如何正确地做它呢?

代码语言:javascript
复制
#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')

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-05 00:25:18

基本上,类定义的外部

代码语言:javascript
复制
std::ostream& operator<<(std::ostream& out, MySpecificClass& c) {
    out << c.Print();
    return out;
}

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63256668

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档