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

时间:2013-12-04 20:48:25

标签: c++ ifstream private-members

我正在尝试在头文件中声明一个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;时会发生错误,删除此行后会消失。可能导致此错误的原因是什么?我错过了一些非常明显的东西,还是有更多的东西?

2 个答案:

答案 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)带领我进行了这一发现。