在 class 中使用 fstream 时遇到问题
Troubles using fstream in a class
编译时出现以下错误:
1>c:\users\ra\source\repos\sandbox\game\gamesetup_1\gamesetup_1\main.cpp(15): error C2280: 'DebugLib::DebugLib(const DebugLib &)': attempting to reference a deleted function
1>c:\users\ra\source\commonincludes\tannic\debuglib\debuglib.h(41): note: compiler has generated 'DebugLib::DebugLib' here
1>c:\users\ra\source\commonincludes\tannic\debuglib\debuglib.h(41): note: 'DebugLib::DebugLib(const DebugLib &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::basic_fstream<char,std::char_traits<char>>::basic_fstream(const std::basic_fstream<char,std::char_traits<char>> &)'
1>c:\program files (x86)\microsoft visual studio17\professional\vc\tools\msvc.16.27023\include\fstream(1421): note: 'std::basic_fstream<char,std::char_traits<char>>::basic_fstream(const std::basic_fstream<char,std::char_traits<char>> &)': function was explicitly deleted
1>Done building project "GameSetup_1.vcxproj" -- FAILED.
代码如下所示:
DebugLib.h:
#include <string>
#include <fstream>
class DebugLib
{
public:
DebugLib(); // Reset timestamp etc.
~DebugLib(); // Flush output buffer
void Init(uint8_t output, std::string fileName = "debug.log"); // Initializes Log
void Log(int category, std::string msg); // Add a line to the log
void Flush(); // Output the remains of the Debug buffer
void Shutdown(); // Shut it down
private:
unsigned int m_initTime;
unsigned int m_bufferPos;
std::string m_outputBuffer[DEBUG_MAXSIZE];
std::fstream m_fileStream;
uint8_t m_output;
bool m_running;
};
main.cpp:
#include <iostream>
#include <DebugLib.h>
using namespace std;
int main()
{
DebugLib gDebugger = DebugLib();
gDebugger.Init(DEBUG_LOG_TO_SCREEN);
cout << "Running!" << endl;
gDebugger.Shutdown();
cin.get();
return 0;
}
我一声明m_fileStream
就收到错误。我的声明有误吗?
当我删除 DebugLib.cpp
中对 m_fileStream
的所有使用时,代码编译正常,并运行(但当然不是参加)
虽然我以前看过这个问题,但我找不到重复的,所以:
让我们从解释错误消息开始。我将忽略行号和错误代码,因为在您理解(或至少阅读)错误消息的其余部分之前,它们很少有用。
'DebugLib::DebugLib(const DebugLib &)': attempting to reference a deleted function
这是主要错误:试图使用已删除的函数,即 DebugLib
的复制构造函数。由于您没有明确指定复制构造函数,因此由编译器为您定义一个。如果可能,编译器将定义一个原始副本。如果这个定义不可行,它会为你删除复制构造函数。
如您所见,编译器能够定义原始副本,直到您添加无法复制的字段(例如 std::fstream
)。
note: compiler has generated 'DebugLib::DebugLib' here
这是一个澄清说明,可帮助错误引用程序中的两行。主要错误消息附带的行号是您尝试进行复制的位置,而此注释附带的行号是生成复制构造函数的位置。编译器试图提供帮助,因为它不知道您要更改哪个位置来解决此错误。
note: 'DebugLib::DebugLib(const DebugLib &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::basic_fstream<char,std::char_traits<char>>::basic_fstream(const std::basic_fstream<char,std::char_traits<char>> &)'
此注释解释了您注意到的事情:无法复制您的 class,因为无法复制 std::fstream
成员。此消息此时使用名称 basic_fstream
,因此有助于了解 fstream
是 basic_fstream
模板的实例。因此,本文末尾的那堆代码只是命名了 std::fstream
.
的复制构造函数
note: 'std::basic_fstream<char,std::char_traits<char>>::basic_fstream(const std::basic_fstream<char,std::char_traits<char>> &)': function was explicitly deleted
这是进一步的澄清。在此之前的行说 "deleted or inaccessible"。此行向 "explicitly deleted".
阐明了这一点
现在我们已经阅读了错误,我们可以去看看它所指的行。麻烦的线路是
DebugLib gDebugger = DebugLib();
此行请求默认构造一个 DebugLib
对象,然后将其复制到 gDebugger
。问题是:它无法复制!解决方案是通过删除副本来简化您的逻辑。您可以直接在 gDebugger
上调用默认构造函数。 (如果您的代码需要它们,这也适用于其他构造函数。)
DebugLib gDebugger{};
作为奖励,您的代码更短。
编译时出现以下错误:
1>c:\users\ra\source\repos\sandbox\game\gamesetup_1\gamesetup_1\main.cpp(15): error C2280: 'DebugLib::DebugLib(const DebugLib &)': attempting to reference a deleted function
1>c:\users\ra\source\commonincludes\tannic\debuglib\debuglib.h(41): note: compiler has generated 'DebugLib::DebugLib' here
1>c:\users\ra\source\commonincludes\tannic\debuglib\debuglib.h(41): note: 'DebugLib::DebugLib(const DebugLib &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::basic_fstream<char,std::char_traits<char>>::basic_fstream(const std::basic_fstream<char,std::char_traits<char>> &)'
1>c:\program files (x86)\microsoft visual studio17\professional\vc\tools\msvc.16.27023\include\fstream(1421): note: 'std::basic_fstream<char,std::char_traits<char>>::basic_fstream(const std::basic_fstream<char,std::char_traits<char>> &)': function was explicitly deleted
1>Done building project "GameSetup_1.vcxproj" -- FAILED.
代码如下所示:
DebugLib.h:
#include <string>
#include <fstream>
class DebugLib
{
public:
DebugLib(); // Reset timestamp etc.
~DebugLib(); // Flush output buffer
void Init(uint8_t output, std::string fileName = "debug.log"); // Initializes Log
void Log(int category, std::string msg); // Add a line to the log
void Flush(); // Output the remains of the Debug buffer
void Shutdown(); // Shut it down
private:
unsigned int m_initTime;
unsigned int m_bufferPos;
std::string m_outputBuffer[DEBUG_MAXSIZE];
std::fstream m_fileStream;
uint8_t m_output;
bool m_running;
};
main.cpp:
#include <iostream>
#include <DebugLib.h>
using namespace std;
int main()
{
DebugLib gDebugger = DebugLib();
gDebugger.Init(DEBUG_LOG_TO_SCREEN);
cout << "Running!" << endl;
gDebugger.Shutdown();
cin.get();
return 0;
}
我一声明m_fileStream
就收到错误。我的声明有误吗?
当我删除 DebugLib.cpp
中对 m_fileStream
的所有使用时,代码编译正常,并运行(但当然不是参加)
虽然我以前看过这个问题,但我找不到重复的,所以:
让我们从解释错误消息开始。我将忽略行号和错误代码,因为在您理解(或至少阅读)错误消息的其余部分之前,它们很少有用。
'DebugLib::DebugLib(const DebugLib &)': attempting to reference a deleted function
这是主要错误:试图使用已删除的函数,即 DebugLib
的复制构造函数。由于您没有明确指定复制构造函数,因此由编译器为您定义一个。如果可能,编译器将定义一个原始副本。如果这个定义不可行,它会为你删除复制构造函数。
如您所见,编译器能够定义原始副本,直到您添加无法复制的字段(例如 std::fstream
)。
note: compiler has generated 'DebugLib::DebugLib' here
这是一个澄清说明,可帮助错误引用程序中的两行。主要错误消息附带的行号是您尝试进行复制的位置,而此注释附带的行号是生成复制构造函数的位置。编译器试图提供帮助,因为它不知道您要更改哪个位置来解决此错误。
note: 'DebugLib::DebugLib(const DebugLib &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::basic_fstream<char,std::char_traits<char>>::basic_fstream(const std::basic_fstream<char,std::char_traits<char>> &)'
此注释解释了您注意到的事情:无法复制您的 class,因为无法复制 std::fstream
成员。此消息此时使用名称 basic_fstream
,因此有助于了解 fstream
是 basic_fstream
模板的实例。因此,本文末尾的那堆代码只是命名了 std::fstream
.
note: 'std::basic_fstream<char,std::char_traits<char>>::basic_fstream(const std::basic_fstream<char,std::char_traits<char>> &)': function was explicitly deleted
这是进一步的澄清。在此之前的行说 "deleted or inaccessible"。此行向 "explicitly deleted".
阐明了这一点现在我们已经阅读了错误,我们可以去看看它所指的行。麻烦的线路是
DebugLib gDebugger = DebugLib();
此行请求默认构造一个 DebugLib
对象,然后将其复制到 gDebugger
。问题是:它无法复制!解决方案是通过删除副本来简化您的逻辑。您可以直接在 gDebugger
上调用默认构造函数。 (如果您的代码需要它们,这也适用于其他构造函数。)
DebugLib gDebugger{};
作为奖励,您的代码更短。