如何解决为什么使用引用成员可以防止删除的构造函数错误? 上下文
上下文
我有两个类(简化为相关声明):
#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_ifstream<_chart _traits>&) [with _CharT = char; _Traits = std::char_traits]'
在最终找到 Error where no default constructor exists for a class 之后,我想我现在明白了:
- 问题是
ifstream
有一个已删除的默认构造函数,它阻止Lexer
在Parser
中使用,因为它没有被提供一个字符串(而Lexer
类本身编译正常)。 - 如果我让
Lexer
直接取一个ifstream
仍然会出现错误(类似上面的推理),因为它还有一个已删除的复制构造函数。 - 通过使
file_
成为引用成员(即std::ifstream &file_;
),解决了缺少复制构造函数的问题,因为成员初始化程序不再尝试使用复制构造函数(因为它只是一个引用)。
我的问题是:
- 我的理解正确吗?感觉有点模糊,但我是 C++ 新手,仍然习惯于在不同的上下文中考虑引用的使用(我理解一般概念)。
- 为什么这里缺少默认构造函数是一个问题,而不是仅声明
Lexer
类(如上)? - 在这里使用引用成员是语义上最正确的解决方案吗?
解决方法
ifstream
确实有一个默认构造函数。由于删除了复制构造函数而粘贴的错误。您编写的代码将不起作用,因为 Lexer
无法使用默认值进行复制构造,因为 ifstream
不可复制。
所以,回答你的问题:
- 您的理解有误;虽然不是一个错误的猜测。
- 与默认构造函数无关。
- 取决于您要尝试做什么。您可能希望防止复制 Lexer,或创建自己的复制构造函数,或使用引用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。