无法在头文件中声明 ifstream 类成员

Can't declare ifstream class member in header file

本文关键字:声明 ifstream 成员 文件      更新时间:2023-10-16

我试图在头文件中声明一个ifstream对象,如图所示,但我收到一个错误,说它无法访问。我尝试过各种方法,比如把它变成一个指针,在.c文件中初始化等等,但我的代码似乎无法得到它的部分声明

ReadFile.h:

#ifndef READFILE_H
#define READFILE_H
#include "cv.h"
#include "highgui.h"
#include <iostream>
#include <fstream>
class ReadFile{
private:
    std::ifstream stream;
public:
    std::string read();
    ReadFile();                                 // Default constructor
    ~ReadFile();                                    // Destructor
};
#endif

ReadFile.c:#包括"ReadFile.h"

ReadFile::ReadFile(){
stream.open("./data.txt");
}
ReadFile::~ReadFile(){
stream.close();
}

我得到的错误是:

Error   9   error C2248: 'std::basic_ifstream<_Elem,_Traits>::basic_ifstream' : cannot access private member declared in class 'std::basic_ifstream<_Elem,_Traits>' c:usersBobdocumentsprojectmodelsreadfile.h    23  1   Project

输出为:

1>c:usersBobdocumentsprojectmodelsreadfile.h(23): error C2248: 'std::basic_ifstream<_Elem,_Traits>::basic_ifstream' : cannot access private member declared in class 'std::basic_ifstream<_Elem,_Traits>'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
1>          c:program files (x86)microsoft visual studio 11.0vcincludefstream(827) : see declaration of 'std::basic_ifstream<_Elem,_Traits>::basic_ifstream'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
1>          This diagnostic occurred in the compiler generated function 'ReadFile::ReadFile(const ReadFile &)'

当包含std::ifstream stream;时会出现错误,当删除该行时会消失。是什么原因导致了这个错误?我是不是错过了一些非常明显的东西,或者还有更多的东西?

问题是std::ifstream没有公共复制构造函数(因为复制一个没有意义),但编译器为类生成的复制构造函数想要使用它。

由于同样的原因,它没有任何可用的赋值运算符(即复制std::ifstream是无稽之谈)。

你也应该禁止为你的班级复制和分配作业。

一个简单的方法是添加

private:
    ReadFile(const ReadFile&);
    ReadFile& operator=(const ReadFile&);

如果你使用的是C++03。

在C++11中,使用= delete语法。

public:
    ReadFile(const ReadFile&) = delete;
    ReadFile& operator=(const ReadFile&) = delete;

这本身不是一个答案,但如果有人在我经历了这么多挣扎之后,在未来遇到这个问题,我决定无论如何都发布它。

由于基本相同的原因,我遇到了一个与OP非常相似的问题,尽管Visual C++给我的错误消息是'ClassName::ClassName(const ClassName &)': attempting to reference a deleted function。在我缺乏经验的头脑中,我在想"WTF,我不会在任何地方复制或分配任何副本!"。

然而,在沮丧地对着电脑尖叫了一个小时后,我把问题缩小到了ifstream班的成员身上,这把我带到了这里。由于得到了公认的答案,我能够将问题进一步缩小到这一行代码:

list.emplace_back(objParam);

我不知道std::vector对象需要在其模板参数的类型上定义一个复制构造函数,以便为将来的emplace_back()调用等保留空间!

因此,解决方案来自Bryan Chen提供的So答案(我补充了重点):

因此,您可以看到template_back确实使用了所需的构造函数来创建元素,并在需要扩展存储时调用复制构造函数您可以提前调用具有足够容量的reserve,以避免调用复制构造函数

感谢Bryan和molbdnilo带领我完成了这一发现。