我正在尝试在头文件中声明一个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: #include“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:\users\Bob\documents\project\models\readfile.h 23 1 Project
输出结果为:
1>c:\users\Bob\documents\project\models\readfile.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.0\vc\include\fstream(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;
时会发生错误,删除此行后会消失。可能导致此错误的原因是什么?我错过了一些非常明显的东西,还是有更多的东西?
答案 0 :(得分:5)
问题是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;
答案 1 :(得分:0)
这本身并不是答案,但是如果以后有人在竭尽全力后遇到这个问题,我还是决定将其发布。
由于基本上相同的原因,我面临着与OP非常相似的问题,尽管Visual C ++给我的错误消息是'ClassName::ClassName(const ClassName &)': attempting to reference a deleted function
。在我缺乏经验的头脑中,我在想“ WTF,我没有在任何地方复制或分配任何副本!”。
但是,在沮丧地尖叫了一个小时之后,我得以将问题缩小到ifstream
类成员,这导致了我的到来。多亏了接受的答案,我得以将问题进一步缩小到以下单行代码:
list.emplace_back(objParam);
我几乎不知道std::vector
对象需要在其模板参数的类型上定义一个复制构造函数,以便为将来的emplace_back()
调用等保留空间!
因此,解决方案来自this SO answer,由Bryan Chen提供(我加了强调):
因此您可以看到emplace_back确实使用所需的构造函数来创建元素,并在需要增加存储量时调用复制构造函数。 您可以预先调用具有足够容量的储备金,以避免调用副本构造函数。
由衷感谢,感谢布莱恩(Bryan)和莫尔布德尼洛(molbdnilo)带领我进行了这一发现。