为什么使用引用成员可以防止删除的构造函数错误



上下文

我有两个类(简化为相关声明(:

#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&lt_CharT,_Traits>:basic_ifstream(const std::basic_iftream<_CharT,_Traits>&([其中_CharT=char;_Traits=std::char_Traits]'

在最终找到一个类不存在默认构造函数的错误后,我想我现在明白了:

  • 问题是ifstream有一个已删除的默认构造函数,它阻止LexerParser中使用,因为它没有被提供字符串(而Lexer类本身编译得很好(
  • 如果我让Lexer直接取一个ifstream,仍然会有一个错误(类似于上面的推理(,因为它也有一个已删除的复制构造函数
  • 通过使file_成为引用成员(即std::ifstream &file_;(,解决了缺少复制构造函数的问题,因为成员初始化器不再尝试使用复制构造函数(因为它只是一个引用(

我的问题是:

  1. 我的理解正确吗?这感觉有点模糊,但我是C++的新手,仍然习惯于在不同的上下文中思考引用的使用(我理解一般概念(
  2. 为什么缺少默认构造函数在这里是一个问题,而不是当只声明Lexer类(如上所述(时
  3. 引用成员的使用是语义上最正确的解决方案吗

ifstream确实有一个默认构造函数。由于复制构造函数已删除,粘贴该错误。您编写的代码将不起作用,因为Lexer不能用默认值进行复制构建,因为ifstream是不可复制的。

因此,为了回答您的问题:

  1. 您的理解不正确;虽然猜测不错
  2. 与默认构造函数无关
  3. 这取决于你试图做什么。你可能想阻止Lexer的复制,或者制作自己的复制构造函数,或者使用引用

最新更新