上下文
我有两个类(简化为相关声明(:
#include <string>
#include <fstream>
class Lexer
{
std::ifstream file_;
Lexer(std::string &file) : file_(file){};
};
class Parser
{
Lexer lexer_;
Parser(Lexer &lex) : lexer_(lex){};
};
这无法编译,出现错误
错误:使用已删除的函数'std::basic_ifstream<_CharT,_Traits>:basic_ifstream(const std::basic_iftream<_CharT,_Traits>&([其中_CharT=char;_Traits=std::char_Traits]'
在最终找到一个类不存在默认构造函数的错误后,我想我现在明白了:
- 问题是
ifstream
有一个已删除的默认构造函数,它阻止Lexer
在Parser
中使用,因为它没有被提供字符串(而Lexer
类本身编译得很好( - 如果我让
Lexer
直接取一个ifstream
,仍然会有一个错误(类似于上面的推理(,因为它也有一个已删除的复制构造函数 - 通过使
file_
成为引用成员(即std::ifstream &file_;
(,解决了缺少复制构造函数的问题,因为成员初始化器不再尝试使用复制构造函数(因为它只是一个引用(
我的问题是:
- 我的理解正确吗?这感觉有点模糊,但我是C++的新手,仍然习惯于在不同的上下文中思考引用的使用(我理解一般概念(
- 为什么缺少默认构造函数在这里是一个问题,而不是当只声明
Lexer
类(如上所述(时 - 引用成员的使用是语义上最正确的解决方案吗
ifstream
确实有一个默认构造函数。由于复制构造函数已删除,粘贴该错误。您编写的代码将不起作用,因为Lexer
不能用默认值进行复制构建,因为ifstream
是不可复制的。
因此,为了回答您的问题:
- 您的理解不正确;虽然猜测不错
- 与默认构造函数无关
- 这取决于你试图做什么。你可能想阻止Lexer的复制,或者制作自己的复制构造函数,或者使用引用