我有一个带有内部类的类,它有一个成员 ifstream。执行代码时,在 if(!datafile->eof())
处的 TestDataHelper::getNextLine()
中抛出 AccessViolationException。
调试显示构造函数工作正常。创建文件并读取第一行。但是当我在分配完成后检查数据文件时(在 TestDataHelper helper = TestDataHelper("data.csv");
之后),数据文件变成了一个无效指针。
代码:
IfstreamTester.h
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
class IfstreamTester
{
public:
IfstreamTester(void);
~IfstreamTester(void);
void doStuff();
private:
std::ifstream file;
class TestDataHelper{
private:
std::ifstream *datafile;
public:
TestDataHelper(std::string filename);
~TestDataHelper();
std::vector<double>* getNextLine();
};
};
IfstreamTester.cpp
#include "IfstreamTester.h"
using namespace std;
IfstreamTester::IfstreamTester(void)
{}
IfstreamTester::~IfstreamTester(void)
{}
void IfstreamTester::doStuff()
{
TestDataHelper helper = TestDataHelper("data.csv");
// for every line in the file
vector<double>* v;
do
{
v = helper.getNextLine();
cout << v << endl;
delete v;
} while(v != NULL);
}
IfstreamTester::TestDataHelper::TestDataHelper(std::string filename)
{
datafile = new ifstream(filename.c_str());
// read the header line
string line;
getline(*datafile, line);
}
vector<double>* IfstreamTester::TestDataHelper::getNextLine()
{
if(!datafile->eof())
{
// readline
string line = "";
getline(*datafile, line);
string delimiter = ",";
vector<double>* res = new vector<double>();
size_t pos = 0;
// and tokenize line into vector of doubles
while ((pos = line.find(delimiter)) != std::string::npos)
{
stringstream conv;
double token;
conv << line.substr(0, pos);
conv >> token;
res->push_back(token);
line.erase(0, pos + delimiter.length());
}
return res;
}
else
{
return NULL;
}
}
IfstreamTester::TestDataHelper::~TestDataHelper()
{
datafile->close();
delete datafile;
}
和主要的:
#include "IfstreamTester.h"
void main()
{
IfstreamTester s = IfstreamTester();
s.doStuff();
}
有人知道为什么会这样吗?
编辑:我正在使用 Microsoft Visual Studio 2008 Express
最佳答案
你的编译器没有给你任何好处。应该是吐了,告诉你std::ifstream
是不可复制的,因此也应隐式删除其包含父级 IfstreamTester
的默认复制构造函数。
我不知道您使用的是什么工具链,但 clang++ 3.3 和 g++ 4.7 都对此感到厌恶。由于复制省略假设,您的编译器显然允许它通过,然后未能在调试中实际省略拷贝。添加一个不成员复制std::ifstream
成员的复制构造函数,或者将main()
声明为:
int main()
{
IfstreamTester s;
s.doStuff();
}
您代码中的非标准 void main()
声明让我(可能不正确地)推断您使用的是 MS 或 Borland 工具链。谁允许这样做(奇数 main()
和不可复制的 std::ifstream
成员被复制),就是不遵守规则。
关于c++ - 具有 ifstream 成员的内部类的构造函数返回无效的 fstream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22195512/