我希望提高代码的效率,特别是从文本文件中读取数据。以下是现在的概况:
values V(name);
V.population = read_value(find_line_number(name, find_in_map(pop, mapping)));
V.net_growth = read_value(find_line_number(name, find_in_map(ngr, mapping)));
... // and so on
基本上,read_value
函数创建一个ifstream
对象,打开文件,读取一行数据,然后关闭文件连接。这种情况多次发生。我想要做的是打开文件一次,读取结构中所需的每一行,然后关闭文件连接。
以下是带参数的创建values
struct函数:
static values create_struct(std::string name, std::map<std::string, int> mapping) {
values V(name);
V.population = read_value(find_line_number(name, find_in_map(pop, mapping)), file);
V.net_growth = read_value(find_line_number(name, find_in_map(ngr, mapping)), file);
// more values here
return V;
}
调用create_struct
的函数如下所示:
void initialize_data(string name) {
// read the appropriate data from file into a struct
value_container = Utility::create_struct(name, this->mapping);
}
我正在考虑在函数initialize_data
中定义ifstream对象。鉴于我的程序显示的内容,这是创建文件对象,打开连接,读取值,然后关闭连接的最佳位置吗?另外,我是否需要将ifstream对象传入create_values
结构,如果是,则按值,引用或指针传递?
答案 0 :(得分:1)
简短的回答是首先创建ifstream对象并将其作为对解析器的引用传递给它。在离开函数或开始阅读之前,请记住要将流回到开头。
RAII要做的就是创建一个包装器对象,当它超出范围时自动执行此操作。
class ifStreamRef{
ifStreamRef(std::ifstream& _in) : mStream(_in){}
~ifStreamRef(){mStream.seekg(0);}
std::ifstream& mStream;
}
然后在输入将读取fstream的方法时创建包装器实例。
void read_value(std::ifstream& input, ...){
ifStreamRef autoRewind(input);
}
或者,因为Ctor可以进行转换......
void read_value(ifStreamRef streamRef, ...) {
streamRef.mStream.getLine(...);
}
std :: ifstream本身跟随RAII,因此当你的流超出范围时,它将为你关闭()流。
答案很长,你应该阅读依赖注入。不要在可共享的对象/函数内创建依赖关系。关于依赖注入和依赖倒置有很多视频和文档。
基本上,构造对象所依赖的对象并将其作为参数传递。
注入现在依赖于您传入的对象的接口。因此,如果您将ifStreamRef类更改为接口:
class ifStreamRef{
ifStreamRef(std::ifstream& _in) : mStream(_in){}
~ifStreamRef(){mStream.seekg(0);}
std::string getLine(){
// todo : mStream.getLine() + return "" on error;
}
bool eof() { return mStream.eof(); }
std::ifstream& mStream;
}
稍后您可以更改引用vector<string>&
而不是ifstream
的内部实现...
class ifStreamRef{
ifStreamRef(std::vector<string>& _in) : mStream(_in), mCursor(0){}
~ifStreamRef(){}
std::string getLine(){
// todo : mStream[mCursor++] + return "" on error;
}
bool eof() { return mCursor >= mStream.size(); }
std::vector<string>& mStream;
size_t mCursor;
}
我过分简化了一些事情。