c++ - 为什么我不能从构造函数初始化 ifstream ref?
问题描述
我正在尝试从构造函数初始化 std::ifstream ref,但我收到一条错误消息
invalid initialization of reference of type ‘std::ifstream& {aka std::basic_ifstream<char>&}’ from expression of type ‘const string {aka const std::__cxx11::basic_string<char>}’
A(const std::string& file_name):inFile(file_name){}
下面是代码
#include <string>
#include <fstream>
class A{
public:
A(const std::string& file_name):inFile(file_name){}
private:
std::ifstream& inFile;
};
int main(){
A("text.txt");
}
解决方案
问题
在
class A{
public:
A(const std::string& file_name):inFile(file_name){}
private:
std::ifstream& inFile;
};
inFile
必须初始化以引用现有的istream
. inFile(file_name)
不构造istream
; 它试图inFile
引用一个string
. 编译器无法使其工作并发出错误。
上面的解释
inFile
不是一个ifstream
。它是对一个变量的引用、别名ifstream
。你不能构造一个引用,因为那里没有任何东西可以构造。它只是已经存在的变量的新名称。必须改为构造引用的变量。
为什么这适用于int
如果你
class A{
public:
A(int & an_Int):int_Ref(an_Int){}
private:
int & int_Ref;
};
int_Ref
指的是指的int
那个an_Int
。如果相反,你
A(int an_int):int_Ref(an_int){}
它仍然会编译,但你有一个问题,因为int_Ref
引用an_int
,一个范围为构造函数的自动变量。an_int
当您将其用于任何事情时,它已经死了并且可能被埋葬了A
。使用int_Ref
将是Undefined Behavior,并且由于行为未定义,任何事情都可能发生,包括您期望的行为。在蚱蜢打喷嚏并且程序突然停止正常工作之前,这可能会欺骗您很长时间。事实上,它从未正常工作过。
A(const std::string& file_name):intRef(file_name){}
由于与上述相同的原因,int
引用不能引用std::string
.
解决方案
有两个合理的选择:
选项1
class A{
public:
A(const std::string& file_name):inFile(file_name){}
private:
std::ifstream inFile; // no longer a reference
};
它将istream
在A
.
选项 2
class A{
public:
A(std::ifstream & in):inFile(in){} // accepts ifstream reference, not string reference
private:
std::ifstream & inFile;
};
它初始化inFile
以引用由 引用的给定的预先存在ifstream
的in
。这意味着
int main(){
A("text.txt");
}
必须成为
int main(){
std::ifstream in("text.txt");
A(in);
}
这伴随着一个警告,即ifstream
提供的 toA
必须具有比A
. 这意味着
A ABuilder(const std::string& file_name)
{
std::ifstream in(file_name);
return A(in);
}
是一个死亡陷阱。返回的A
包含对不再存在的对象的引用。
由于选项 2 出错的可能性增加,我建议首选选项 1
推荐阅读
- python-3.x - 如何组合包含字符串和 int 的两行?
- python - Python 中的 Bland Altman Plot 未显示 TickLabels
- python - 如何使用 PyGithub 从一个提交更改到另一个分支?
- javascript - 如何在redux react.js的reducer函数中进行多重分配和添加操作?
- google-apps-script - Google 使用 Apps 脚本项目登录 Web 应用程序 - 错误 400:redirect_uri_mismatch
- python - 我想将字典的值重新映射到数据框中
- php - 如何通过ajax发送多个复选框值
- python - 打印函数中的值列表,但也需要返回它
- java - WebLogic java.lang.OutOfMemoryError:Java 堆空间
- java - 访问HashMap中抽象类的子类