tannic
tannic

Reputation: 39

Troubles using fstream in a class

I get the following error, when compiling:

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 studio\2017\professional\vc\tools\msvc\14.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.

The code looks like this:

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;
}

As soon as I declare m_fileStream I get the error. Do I have a wrong declaration ? When I remove all the use of m_fileStream in DebugLib.cpp, the code compiles fine, and runs (but of course not as attended)

Upvotes: 2

Views: 123

Answers (1)

JaMiT
JaMiT

Reputation: 17072

I couldn't find a duplicate even though I've seen this asked before, so:

Let's start by explaining the error messages. I'll ignore the line numbers and error codes, as those are rarely useful until after you've understood (or at least read) the rest of the error message.

'DebugLib::DebugLib(const DebugLib &)': attempting to reference a deleted function

This is the main error: an attempt to use a function that is deleted, namely the copy constructor for DebugLib. Since you did not explicitly specify a copy constructor, it is up to the compiler to define one for you. The compiler will define a naive copy if possible. If this definition is not possible, it will delete the copy constructor for you.

As you noticed, the compiler is able to define a naive copy until you add a field that cannot be copied (such as std::fstream).

note: compiler has generated 'DebugLib::DebugLib' here

This is a clarifying note that helps the error refer to two lines in your program. The line number that came with the main error message is where you tried to do the copy, and the line number that comes with this note is where the copy constructor is generated. The compiler is trying to be helpful because it doesn't know which location you'll want to change to address this error.

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>> &)'

This note explains the thing you noticed: copying your class is prevented because the std::fstream member cannot be copied. This message uses the name basic_fstream at this point, so it helps to know that fstream is an instantiation of the basic_fstream template. So that mess of code at the end of this note just names the copy constructor of 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

This is a further clarification. The line before this said "deleted or inaccessible". This line clarifies that to "explicitly deleted".

Now that we have read the error, we can go look at the lines to which it refers. The troublesome line is

  DebugLib gDebugger = DebugLib();

This line requests that a DebugLib object be default constructed then copied to gDebugger. And there's the problem: it cannot be copied! The solution is to simplify your logic by removing the copy. You can invoked the default constructor directly on gDebugger. (This works for other constructors as well, should your code need them.)

    DebugLib gDebugger{};

As a bonus, your code is shorter.

Upvotes: 3

Related Questions